Какие преимущества делает использование (функция (окно, документ, undefined) {...}) (окно, документ)?
Я предполагаю, что использование этого шаблона - это новая жара, но я не понимаю, что это за преимущество, и я не понимаю его видимость.
Образец:
(function(window, document, undefined){
window.MyObject = {
methodA: function() { ... },
methodB: function() { ... }
};
})(window, document)
У меня есть несколько вопросов об этом.
Есть ли конкретное преимущество для инкапсуляции объекта, подобного этому?
Почему окна и документы подаются вместо обычного доступа?
Почему передается undefined
?
Является ли прикрепление объекта, который мы создаем непосредственно к окну, особенно хорошая идея?
Я привык к тому, что я назову в стиле Crockford для инкапсуляции Javascript (потому что я получил его от видеороликов Douglas Crockford Javascript).
NameSpace.MyObject = function() {
// Private methods
// These methods are available in the closure
// but are not exposed outside the object we'll be returning.
var methodA = function() { ... };
// Public methods
// We return an object that uses our private functions,
// but only exposes the interface we want to be available.
return {
methodB: function() {
var a = methodA();
},
methodC: function() { ... }
}
// Note that we're executing the function here.
}();
Является ли один из этих шаблонов функционально лучше другого? Является ли первая эволюцией другой?
Ответы
Ответ 1
Почему для доступа к окну и документам вместо обычного доступа?
Как правило, чтобы закрепить процесс разрешения идентификатора, использование их в качестве локальных переменных может помочь (хотя IMO может улучшить производительность).
Передача глобального объекта также является широко используемым методом в нерабочих средах, где у вас нет идентификатора window
в глобальной области видимости, например:
(function (global) {
//..
})(this); // this on the global execution context is
// the global object itself
Почему передается undefined?
Это сделано потому, что глобальное свойство undefined
в ECMAScript 3 является изменчивым, что означает, что кто-то может изменить его значение, влияющее на ваш код, например:
undefined = true; // mutable
(function (undefined) {
alert(typeof undefined); // "undefined", the local identifier
})(); // <-- no value passed, undefined by default
Если вы внимательно посмотрите undefined
на самом деле не передается (нет аргумента в вызове функции), это один из надежных способов получить значение undefined
без использования свойства window.undefined
.
Имя undefined
в JavaScript не означает ничего особенного, это не ключевое слово, как true
, false
и т.д., это просто идентификатор.
Только для записи в ECMAScript 5 это свойство было сделано незаписываемым...
Является ли прикрепление объекта, который мы создаем непосредственно к окну, особенно хорошая идея?
Это обычный способ, используемый для объявления глобальных свойств, когда вы находитесь в другой области функций.
Ответ 2
Этот особый стиль приносит определенные преимущества над стилем "Crockford". В первую очередь, передача window
и document
позволяет более эффективно минимизировать script. A minifier может переименовать эти параметры в односимвольные имена, сохраняя 5 и 7 байтов соответственно для каждой ссылки. Это может складываться: ссылки jQuery window
33 раза и document
91 раз. Минимизация каждого токена до одного символа сохраняет 802 байта.
Кроме того, вы получаете преимущество скорости выполнения. Когда я впервые прочитал утверждение @joekarl, что он дает преимущество в производительности, я подумал: "Это кажется довольно ложным". Таким образом, я профилировал фактическую производительность с помощью тестовой страницы. Ссылаясь на window
сто миллионов раз, локальная ссылка на переменные обеспечивает скромное увеличение скорости на 20% (от 4200 мс до 3400 мс) в Firefox 3.6 и шокирующее увеличение на 31 000% (с 13 до 400 мс) в Chrome 9.
Конечно, вы никогда не будете ссылаться на window
100 000 000 раз на практике, и даже 10 000 прямых ссылок берут только 1 мс в Chrome, поэтому фактическое увеличение производительности здесь почти полностью пренебрежимо мало.
Почему передается undefined
?
Потому что (как упоминалось @CMS) токен undefined
на самом деле undefined. В отличие от null
, он не имеет особого значения, и вы можете назначить этот идентификатор, как любое другое имя переменной. (Обратите внимание, однако, что это больше не соответствует true в ECMAScript 5.)
Является ли прикрепление объекта, который мы создаем непосредственно к окну, особенно хорошая идея?
Объект window
- это глобальная область действия, так что именно то, что вы делаете в какой-то момент, независимо от того, вы или нет, явно написано "окно". window.Namespace = {};
и Namespace = {};
эквивалентны.
Ответ 3
Я с тобой использую стиль Крокфорда.
Чтобы ответить на ваши вопросы
1.Есть ли конкретное преимущество для инкапсуляции такого объекта?
Единственное преимущество, которое я вижу, заключается в создании локальных переменных окна и документа вместо глобальных переменных, вы получаете некоторую дополнительную безопасность, не имея возможности напрямую перезаписывать один из них, а также некоторое усиление производительности, поскольку оба они являются локальными.
2. Почему окна и документ подаются вместо обычного доступа?
. Локальные переменные, как правило, быстрее, но с jit-компиляцией в эти дни, которые становятся номинальными.
3.Что вы передаете undefined в?
Нет подсказки....
4. Прикрепляет ли мы объект, который мы создаем непосредственно к окну, особенно хорошая идея?
Возможно, нет, но я все равно придерживаюсь шаблона Крокфорда, поскольку привязка функции к объекту окна предоставляет ее остальной части глобального стека через оконный объект, а не подвергая его воздействию нестандартного пространства имен.
Ответ 4
Я думаю, что это в основном для кода, который нужно запускать в нескольких контекстах окна. Скажем, у вас сложное приложение с большим количеством фреймов и/или дочерних окон. Все они должны запускать код в MyObject, но вы хотите загрузить его только один раз. Таким образом, вы загружаете его в любом выбранном окне/кадре, но вы создаете MyObject для каждого окна/фрейма со ссылками на правильное окно и документ.
Взятие аргумента undefined пытается защитить от факта, что undefined можно изменить:
undefined = 3;
alert(undefined);
См. ответ CMS о том, как это повышает безопасность.