Как работает этот синтаксис JavaScript / jQuery: (функция (окно, неопределенное) {}) (окно)? - PullRequest
152 голосов
/ 26 апреля 2010

Вы когда-нибудь заглядывали под капот на исходный код jQuery 1.4 и заметили, как он инкапсулируется следующим образом:

(function( window, undefined ) {

  //All the JQuery code here 
  ...

})(window);

Я прочитал статью о Пространстве имен JavaScript и еще одну статью под названием " Важная пара паренов ", поэтому я немного знаю о том, что здесь происходит.

Но я никогда раньше не видел этот конкретный синтаксис. Что там делает undefined? И почему window необходимо пройти, а затем снова появиться в конце?

Ответы [ 5 ]

157 голосов
/ 26 апреля 2010

undefined является нормальной переменной и может быть изменен просто с помощью undefined = "new value";. Таким образом, jQuery создает локальную «неопределенную» переменную, которая ДЕЙСТВИТЕЛЬНО не определена.

Переменная окна сделана локальной из соображений производительности. Потому что, когда JavaScript ищет переменную, он сначала просматривает локальные переменные, пока не найдет имя переменной. Когда он не найден, JavaScript проходит через следующую область и т. Д., Пока не отфильтрует глобальные переменные. Таким образом, если переменная окна сделана локальной, JavaScript сможет быстрее ее найти. Дополнительная информация: Ускорьте свой JavaScript - Николас С. Закас

53 голосов
/ 09 февраля 2011

Не определено

Объявляя undefined в качестве аргумента, но никогда не передавая ему значение, мы гарантируем, что оно всегда неопределено, поскольку это просто переменная в глобальной области видимости, которую можно перезаписать. Это делает a === undefined безопасной альтернативой typeof a == 'undefined', которая сохраняет несколько символов. Это также делает код более понятным для миниторов, так как, например, undefined можно сократить до u, сохранив еще несколько символов.

Окно

Передача window в качестве аргумента сохраняет копию в локальной области, что влияет на производительность: http://jsperf.com/short-scope. Все обращения к window теперь должны будут проходить на один уровень меньше по цепочке областей. Как и в случае undefined, локальная копия снова позволяет более агрессивно минимизировать.


Sidenote:

Хотя это, возможно, и не было целью разработчиков jQuery, передача window позволяет более легко интегрировать библиотеку в среды Javascript на стороне сервера, например, node.js - там, где не является глобальным window объектом. В такой ситуации необходимо изменить только одну строку, чтобы заменить объект window другой. В случае jQuery, фиктивный window объект может быть создан и передан с целью очистки HTML (библиотека, такая как jsdom , может сделать это).

16 голосов
/ 26 апреля 2010

Другие объяснили undefined. undefined похоже на глобальную переменную, которую можно переопределить для любого значения. Этот метод предотвращает взлом всех неопределенных проверок, если кто-то написал, скажем, undefined = 10 где-нибудь. Аргумент, который никогда не передается, гарантированно будет действительным undefined независимо от значения переменной undefined.

Причина прохождения окна может быть проиллюстрирована на следующем примере.

(function() {
   console.log(window);
   ...
   ...
   ...
   var window = 10;
})();

Что записывает консоль? Значение window объекта верно? Неправильно! 10? Неправильно! Журналы undefined. Интерпретатор Javascript (или JIT-компилятор) переписывает его следующим образом -

(function() {
   var window; //and every other var in this function

   console.log(window);
   ...
   ...
   ...
   window = 10;

})();

Однако, если вы получите переменную window в качестве аргумента, переменная отсутствует и, следовательно, не будет сюрпризов.

Я не знаю, делает ли это jQuery, но если по какой-либо причине вы переопределяете локальную переменную window в любом месте вашей функции, было бы неплохо позаимствовать ее из глобальной области.

6 голосов
/ 26 апреля 2010

window передается таким образом, на случай, если кто-то решит переопределить объект окна в IE, я предполагаю то же самое для undefined, на случай, если он будет переназначен каким-либо образом позже.

Верх window в этом скрипте просто называет аргумент «окно», более локальный аргумент, чем глобальная ссылка window, и то, что будет использовать код внутри этого замыкания. window в конце фактически указывает, что передать первому аргументу, в данном случае текущее значение window ... надеюсь, вы не облажались window до того, как это произойдет.

Об этом может быть проще подумать, показывая наиболее типичный случай, используемый в jQuery, плагин .noConflict(), поэтому для большей части кода вы все равно можете использовать $, даже если это что-то другое , чем jQuery вне этой области:

(function($) {
  //inside here, $ == jQuery, it was passed as the first argument
})(jQuery);
5 голосов
/ 11 марта 2012

Протестировано с 1000000 итераций. Этот вид локализации не повлиял на производительность. Ни одной миллисекунды за 1000000 итераций. Это просто бесполезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...