Короче
Краткое описание
В своей простейшей форме этот метод направлен на обертывание кода внутри области действия .
Помогает уменьшить шансы:
- конфликт с другими приложениями / библиотеками
- загрязняющий превосходящий (наиболее вероятный глобальный) охват
Он не не определяет, когда документ готов - это не какой-то document.onload
или window.onload
Он обычно известен как Immediately Invoked Function Expression (IIFE)
или Self Executing Anonymous Function
.
объясненный код
var someFunction = function(){ console.log('wagwan!'); };
(function() { /* function scope starts here */
console.log('start of IIFE');
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})(); /* function scope ends */
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
В приведенном выше примере любая переменная, определенная в функции (т. Е. Объявленная с использованием var
), будет "частной" и доступна ТОЛЬКО в области действия функции (как выразился Вивин Палиат). Другими словами, эти переменные не видны / недоступны вне функции. Смотрите живое демо .
Javascript имеет функцию определения области видимости. «Параметры и переменные, определенные в функции, не видны вне функции, и что переменная, определенная где-либо внутри функции, видна везде внутри функции». (из "Javascript: хорошие части").
Подробнее
Альтернативный код
В конце код, размещенный ранее, также можно сделать следующим образом:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
};
myMainFunction(); // I CALL "myMainFunction" FUNCTION HERE
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Смотрите демо-версию .
Корни
Итерация 1
Однажды кто-то, вероятно, подумал: «Должен быть способ избежать именования« myMainFunction », поскольку все, что нам нужно, - это выполнить его немедленно».
Если вы вернетесь к основам, вы обнаружите, что:
expression
: что-то, оценивающее значение. т.е. 3+11/x
statement
: строки кода делают что-то, НО это делает , а не вычисляет значение. т.е. if(){}
Аналогичным образом, выражения функций оцениваются как значения. И одно из следствий (я полагаю?) Заключается в том, что они могут быть немедленно вызваны:
var italianSayinSomething = function(){ console.log('mamamia!'); }();
Итак, наш более сложный пример:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
}();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Посмотреть демо-версию .
Итерация 2
Следующим шагом является мысль «зачем иметь var myMainFunction =
, если мы даже не используем его!?».
Ответ прост: попробуйте удалить это, как показано ниже:
function(){ console.log('mamamia!'); }();
Смотрите демо-версию .
Это не будет работать, потому что "объявления функций не могут быть вызваны" .
Хитрость в том, что, удалив var myMainFunction =
, мы преобразовали выражение функции в объявление функции . Для получения более подробной информации см. Ссылки в разделе «Ресурсы».
Следующий вопрос: «Почему я не могу сохранить его как выражение функции с чем-то отличным от var myMainFunction =
?
Ответ: «Вы можете», и на самом деле есть много способов сделать это: добавив +
, !
, -
или, возможно, заключив в скобки пару (как сейчас сделано по договоренности) и больше я верю. Как пример:
(function(){ console.log('mamamia!'); })(); // live demo: jsbin.com/zokuwodoco/1/edit?js,console.
или
+function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wuwipiyazi/1/edit?js,console
или
-function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wejupaheva/1/edit?js,console
Таким образом, как только соответствующая модификация добавлена к тому, что когда-то было нашим «Альтернативным кодом», мы возвращаемся к тому же коду, который использовался в примере «Объясненный код»
var someFunction = function(){ console.log('wagwan!'); };
(function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Подробнее о Expressions vs Statements
:
Демистифицирующие прицелы
Одна вещь, которая может задаться вопросом: «что происходит, когда вы НЕ определяете переменную« должным образом »внутри функции - т.е. вместо этого делаете простое присваивание?»
(function() {
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
myOtherFunction = function(){ /* oops, an assignment instead of a declaration */
console.log('haha. got ya!');
};
})();
myOtherFunction(); // reachable, hence works: see in the console
window.myOtherFunction(); // works in the browser, myOtherFunction is then in the global scope
myFunction(); // unreachable, will throw an error, see in the console
Смотрите демо-версию .
В основном, если переменной, которая не была объявлена в ее текущей области действия, присваивается значение, то «поиск цепочки области действия происходит до тех пор, пока она не найдет переменную или не достигнет глобальной области (в какой момент она ее создаст)» .
В браузерной среде (по сравнению с серверной средой, такой как nodejs) глобальная область определяется объектом window
. Следовательно, мы можем сделать window.myOtherFunction()
.
Мой совет «Надлежащей практики» по этой теме: всегда используйте var
при определении чего-либо : будь то число, объект или функция и даже в глобальной области. Это делает код намного проще.
Примечание:
- JavaScript не не имеет
block scope
(Обновление: локальные переменные области видимости блока добавлены в ES6 .)
- javascript имеет только
function scope
& global scope
(window
область действия в среде браузера)
Подробнее о Javascript Scopes
:
Ресурсы
Следующие шаги
Как только вы получите эту концепцию IIFE
, это приведет к module pattern
, что обычно достигается путем использования этого шаблона IIFE. Веселитесь:)