`новая функция ()` с нижним регистром "f" в JavaScript

Мой коллега использовал «новую функцию ()» в нижнем регистре «f» для определения новых объектов в JavaScript. Похоже, что он хорошо работает во всех основных браузерах, а также довольно эффективен для сокрытия закрытых переменных. Вот пример:

    var someObj = new function () {
        var inner = 'some value';
        this.foo = 'blah';

        this.get_inner = function () {
            return inner;
        };

        this.set_inner = function (s) {
            inner = s;
        };
    };

Как только "this" используется, оно становится общедоступным свойством someObj. Так что someObj.foo, someObj.get_inner () и someObj.set_inner () доступны для всех. Кроме того, set_inner () и get_inner () являются привилегированными методами, поэтому они имеют доступ к «внутреннему» через замыкания.

Однако я нигде не видел ссылок на эту технику. Даже JSLint Дугласа Крокфорда жалуется на это:

  
  • странная конструкция. Удалить "новый"
  •   

Мы используем эту технику в производстве, и она, кажется, работает хорошо, но я немного беспокоюсь об этом, потому что она нигде не документирована. Кто-нибудь знает, если это допустимая техника?

105 голосов | спросил Johnny Oshika 16 FebruaryEurope/MoscowbTue, 16 Feb 2010 20:01:13 +0300000000pmTue, 16 Feb 2010 20:01:13 +030010 2010, 20:01:13

3 ответа


0

Я видел эту технику раньше, она действительна, вы используете выражение функции, как если бы это было Функция конструктора .

Но ИМХО, вы можете добиться того же самого с помощью выражения, вызывающего функцию автоматически. Я не вижу смысла в использовании new оператор таким образом:

var someObj = (function () {
    var instance = {},
        inner = 'some value';

    instance.foo = 'blah';

    instance.get_inner = function () {
        return inner;
    };

    instance.set_inner = function (s) {
        inner = s;
    };

    return instance;
})();

Цель оператора new - создавать новые экземпляры объектов, настраивая [[Prototype]], вы можете увидеть, как это делается с помощью [Construct] внутреннее свойство.

Приведенный выше код даст эквивалентный результат.

ответил CMS 16 FebruaryEurope/MoscowbTue, 16 Feb 2010 20:07:44 +0300000000pmTue, 16 Feb 2010 20:07:44 +030010 2010, 20:07:44
0

Ваш код похож на менее странную конструкцию

function Foo () {
    var inner = 'some value';
    this.foo = 'blah';

    ...
};
var someObj = new Foo;
ответил kennytm 16 FebruaryEurope/MoscowbTue, 16 Feb 2010 20:08:09 +0300000000pmTue, 16 Feb 2010 20:08:09 +030010 2010, 20:08:09
0

Чтобы прояснить некоторые аспекты и заставить JSLint Дугласа Крокфорда не жаловаться на ваш код, вот несколько примеров:

 1. o = new Object(); // normal call of a constructor

2. o = new Object;   // accepted call of a constructor

3. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
})(); // normal call of a constructor

4. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
}); // accepted call of a constructor

В примере 3. Выражение в (...) в качестве значения является функцией /конструктором. Это выглядит так: new (function () {...}) (). Поэтому, если мы опускаем конечные скобки, как в примере 2, выражение все еще является допустимым вызовом конструктора и выглядит как пример 4.

JSLint Дугласа Крокфорда «думает», что вы хотите присвоить функцию someObj, а не ее экземпляру. А ведь это всего лишь предупреждение, а не ошибка.

ответил DUzun 28 32012vEurope/Moscow11bEurope/MoscowWed, 28 Nov 2012 12:07:13 +0400 2012, 12:07:13

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132