`новая функция ()` с нижним регистром "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 Дугласа Крокфорда жалуется на это:
- странная конструкция. Удалить "новый"
Мы используем эту технику в производстве, и она, кажется, работает хорошо, но я немного беспокоюсь об этом, потому что она нигде не документирована. Кто-нибудь знает, если это действительная техника?
3 ответа
Я уже видел эту технику раньше, она действительна, вы используете выражение функции, как если бы это была функция конструктора.
Но ИМХО, вы можете добиться того же самого с помощью выражения автозапускаемой функции, я не вижу смысла в использовании 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]
внутренняя собственность.
Приведенный выше код даст эквивалентный результат.
Ваш код просто похож на менее странную конструкцию
function Foo () {
var inner = 'some value';
this.foo = 'blah';
...
};
var someObj = new Foo;
Чтобы прояснить некоторые аспекты и сделать так, чтобы 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, а не ее экземпляру. А ведь это всего лишь предупреждение, а не ошибка.