(function() {})()и его кузен, специфичный для jQuery, постоянно (function($) {})(jQuery)появляется в коде Javascript.
Как работают эти конструкции и какие проблемы они решают?
Примеры оценены
(function() {})()и его кузен, специфичный для jQuery, постоянно (function($) {})(jQuery)появляется в коде Javascript.
Как работают эти конструкции и какие проблемы они решают?
Примеры оценены
jQueryприводит в качестве аргумента.
Ответы:
С ростом популярности фреймворков JavaScript этот $знак использовался во многих различных случаях. Итак, чтобы уменьшить возможные конфликты, вы можете использовать эти конструкции:
(function ($){
// Your code using $ here.
})(jQuery);
В частности, это объявление анонимной функции, которое выполняется немедленно, передавая в качестве параметра основной объект jQuery. Внутри этой функции вы можете использовать $для ссылки на этот объект, не беспокоясь о том, что другие фреймворки также находятся в области видимости.
Это метод, используемый для ограничения области действия переменных; это единственный способ предотвратить загрязнение глобального пространства имен переменными.
var bar = 1; // bar is now part of the global namespace
alert(bar);
(function () {
var foo = 1; // foo has function scope
alert(foo);
// code to be executed goes here
})();
1) Он определяет анонимную функцию и сразу ее выполняет.
2) Обычно это делается, чтобы не засорять глобальное пространство имен нежелательным кодом.
3) Вам нужно открыть некоторые методы из него, все, что объявлено внутри, будет «приватным», например:
MyLib = (function(){
// other private stuff here
return {
init: function(){
}
};
})();
Или, альтернативно:
MyLib = {};
(function({
MyLib.foo = function(){
}
}));
Дело в том, что есть много способов его использования, но результат остается неизменным.
Это просто анонимная функция, которая вызывается немедленно. Вы можете сначала создать функцию, а затем вызвать ее, и вы получите тот же эффект:
(function(){ ... })();
работает как:
temp = function(){ ... };
temp();
Вы также можете сделать то же самое с именованной функцией:
function temp() { ... }
temp();
Код, который вы называете jQuery-специфичным, является только в том смысле, что вы используете в нем объект jQuery. Это просто анонимная функция с параметром, которая вызывается немедленно.
Вы можете сделать то же самое в два этапа, и вы можете сделать это с любыми параметрами, которые вам нравятся:
temp = function(answer){ ... };
temp(42);
Проблема, которую это решает, заключается в том, что он создает закрытие кода в функции. Вы можете объявлять в нем переменные, не загрязняя глобальное пространство имен, тем самым снижая риск конфликтов при использовании одного скрипта вместе с другим.
В конкретном случае для jQuery вы используете его в режиме совместимости, когда он не объявляет имя $ как псевдоним для jQuery. Отправив объект jQuery в закрытие и указав параметр $, вы все равно можете использовать тот же синтаксис, что и без режима совместимости.
Это объясняет здесь , что ваша первая конструкция обеспечивает простор для переменных.
Переменные ограничены на уровне функций в javascript. Это отличается от того, к чему вы могли бы привыкнуть в таких языках, как C # или Java, где переменные привязаны к блоку. Это означает, что если вы объявите переменную внутри цикла или оператора if, она будет доступна для всей функции.
Если вам когда-нибудь понадобится явно указать область видимости переменной внутри функции, вы можете использовать для этого анонимную функцию. Фактически вы можете создать анонимную функцию, а затем сразу выполнить ее, и все переменные внутри будут привязаны к анонимной функции:
(function() {
var myProperty = "hello world";
alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
Еще одна причина сделать это - устранить путаницу в том, какой $оператор фреймворка вы используете. Например, чтобы заставить jQuery, вы можете сделать:
;(function($){
... your jQuery code here...
})(jQuery);
Передавая $оператор в качестве параметра и вызывая его в jQuery, $оператор внутри функции блокируется для jQuery, даже если у вас загружены другие фреймворки.
Еще одно применение этой конструкции - «захват» значений локальных переменных, которые будут использоваться в замыкании. Например:
for (var i = 0; i < 3; i++) {
$("#button"+i).click(function() {
alert(i);
});
}
Приведенный выше код заставит все три кнопки выскочить "3". С другой стороны:
for (var i = 0; i < 3; i++) {
(function(i) {
$("#button"+i).click(function() {
alert(i);
});
})(i);
}
Это заставит три кнопки выскочить «0», «1» и «2», как и ожидалось.
Причина в том, что замыкание сохраняет ссылку на включающий его стековый фрейм , в котором хранятся текущие значения его переменных. Если эти переменные изменяются до выполнения закрытия, то при закрытии будут отображаться только последние значения, а не значения, которые были на момент создания закрытия. Если заключить создание замыкания в другую функцию, как во втором примере выше, текущее значение переменной iсохраняется в кадре стека анонимной функции.
Это считается закрытием . Это означает, что содержащийся в нем код будет работать в пределах своей лексической области. Это означает, что вы можете определять новые переменные и функции, и они не будут конфликтовать с пространством имен, используемым в коде за пределами замыкания.
var i = 0;
alert("The magic number is " + i);
(function() {
var i = 99;
alert("The magic number inside the closure is " + i);
})();
alert("The magic number is still " + i);
Это сгенерирует три всплывающих окна, демонстрирующих, что iв закрытии не изменяется ранее существовавшая переменная с тем же именем:
Они часто используются в плагинах jQuery. Как объясняется в Руководстве по созданию плагинов jQuery, все переменные, объявленные внутри, { }являются частными и не видны снаружи, что обеспечивает лучшую инкапсуляцию.
{}сами по себе не создают новую область видимости в JavaScript. Область видимости создается объявлением функции.
Как говорили другие, они оба определяют анонимные функции, которые вызываются немедленно. Обычно я оборачиваю свои объявления классов JavaScript в эту структуру, чтобы создать статическую частную область видимости для класса. Затем я могу разместить в этой области постоянные данные, статические методы, обработчики событий или что-либо еще, и это будет видно только экземплярам класса:
// Declare a namespace object.
window.MyLibrary = {};
// Wrap class declaration to create a private static scope.
(function() {
var incrementingID = 0;
function somePrivateStaticMethod() {
// ...
}
// Declare the MyObject class under the MyLibrary namespace.
MyLibrary.MyObject = function() {
this.id = incrementingID++;
};
// ...MyObject's prototype declaration goes here, etc...
MyLibrary.MyObject.prototype = {
memberMethod: function() {
// Do some stuff
// Maybe call a static private method!
somePrivateStaticMethod();
}
};
})();
В этом примере MyObjectкласс назначен MyLibraryпространству имен, поэтому он доступен. incrementingIDи somePrivateStaticMethod()не доступны напрямую за пределами анонимной функции.
Это в основном для пространства имен вашего кода JavaScript.
Например, вы можете поместить туда любые переменные или функции, а снаружи они не существуют в этой области. Поэтому, когда вы инкапсулируете все внутри, вам не нужно беспокоиться о конфликтах.
В ()конце означает самовызов. Вы также можете добавить туда аргумент, который станет аргументом вашей анонимной функции. Я часто делаю это с помощью jQuery, и вы понимаете, почему ...
(function($) {
// Now I can use $, but it won't affect any other library like Prototype
})(jQuery);
Эван Тримболи покрывает остальное в своем ответе .
Приведенный выше код создает анонимную функцию в строке 1, а затем вызывает ее в строке 3 с 0 аргументами. Это эффективно инкапсулирует все функции и переменные, определенные в этой библиотеке, потому что все функции будут доступны только внутри этой анонимной функции.
Это хорошая практика, и причина этого заключается в том, чтобы избежать загрязнения глобального пространства имен переменными и функциями, которые могут быть заторможены другими частями Javascript по всему сайту.
Чтобы пояснить, как вызывается функция, рассмотрим простой пример:
Если у вас есть эта единственная строка Javascript, она будет вызываться автоматически, не вызывая ее явно:
alert('hello');
Итак, возьмите эту идею и примените ее к этому примеру:
(function() {
alert('hello')
//anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked
Конечный результат аналогичен, потому что анонимная функция вызывается так же, как в предыдущем примере.
//here, the anonymous function is invoked, просто, но я этого раньше не видел :)
Потому что хорошие ответы на код уже приняты :) Я предлагаю посмотреть несколько видеороликов Джона Ресига, видео 1 , видео 2 (изобретатель jQuery и мастер в JavaScript).
Некоторые действительно хорошие идеи и ответы представлены в видео.
Именно этим я и занимался в тот момент, когда увидел ваш вопрос.
function(){ // some code here }
- это способ определить анонимную функцию в javascript. Они могут дать вам возможность выполнять функцию в контексте другой функции (в противном случае у вас может не быть этой возможности).