Javascript сразу вызвал функциональные шаблоны
Как вы называете эти шаблоны? В чем разница между ними? Когда вы будете использовать их? Есть ли другие подобные шаблоны?
(function() {
console.log(this); // window
})();
(function x() {
console.log(this); // window
})();
var y = (function() {
console.log(this); // window
})();
var z = function() {
console.log(this); // window
}();
EDIT: Я только что нашел еще два, казалось бы, избыточных способа сделать это, назвав функции в последних двух случаях...
var a = (function foo() {
console.log(this); // window
})();
var b = function bar() {
console.log(this);
}();
EDIT2: Вот еще один шаблон, приведенный ниже в @GraceShao, который делает функцию доступной вне области действия.
(x = function () {
console.log(this); // window
console.log(x); // function x() {}
})();
console.log(x); // function x() {}
// I played with this as well
// by naming the inside function
// and got the following:
(foo = function bar() {
console.log(this); // window
console.log(foo); // function bar() {}
console.log(bar); // function bar() {}
})();
console.log(foo); // function bar() {}
console.log(bar); // undefined
Ответы
Ответ 1
Вот ваши функции снова с некоторыми комментариями, описывающими, когда/почему они могут быть полезны:
(function() {
// Create a new scope to avoid exposing variables that don't need to be
// This function is executed once immediately
})();
(function fact(i) {
// This named immediately invoked function is a nice way to start off recursion
return i <= 1 ? 1 : i*fact(i - 1);
})(10);
var y = (function() {
// Same as the first one, but the return value of this function is assigned to y
return "y value";
})();
var z = function() {
// This is the exact same thing as above (except it assigned to z instead of y, of course).
// The parenthesis in the above example don't do anything since this is already an expression
}();
Ответ 2
В этом случае они все семантически идентичны. Спецификация ECMAScript содержит полные правила производства, поэтому это грубое упрощение.
Также обратите внимание, что я игнорирую имя названной функции (x
), поскольку имя не используется; он может ссылаться внутри тела, но поскольку это FunctionExpression (через производство грамматики), он никогда (в правильной реализации JS) не загрязнит область видимости - см. комментарии.
(function() {
console.log(this); // window
})();
(function x() {
console.log(this); // window
})();
var y = (function() {
console.log(this); // window
})();
var z = function() {
console.log(this); // window
}();
Уменьшено (тела в этом случае несущественны, все они возвращают undefined "):
(function() {})();
(function x() {})();
var y = (function() {})();
var z = function() {}();
Сокращение (в грамматике ECMAScript FunctionExpression
- это производственное правило, но здесь я использую его как "выражение, которое является функцией" ):
FunctionExpression()
FunctionExpression()
var y = FunctionExpression()
var z = FunctionExpression()
Игнорируя присвоение результата (которое всегда было бы undefined
), можно видеть, что все формы одинаковы.
Счастливое кодирование.
Ответ 3
Self-вызов функции анонимного. Тело функции будет вызвано немедленно.
(function() {
console.log(this); // window
})();
Функция самозапуска. Тело функции будет вызвано немедленно. Вы можете по-прежнему ссылаться на функцию x
внутри тела функции. Поэтому, когда вы хотите выполнить что-то сразу, а затем вы можете захотеть итерации, вы можете просто ссылаться на него напрямую.
(function x() {
console.log(this); // window
console.log(x); // function x() {}
})();
Вызов вызывающей анонимной функции с правой стороны будет вызываться немедленно, а возвращаемое значение будет присвоено y
. Обычно он имеет возвращаемое значение, когда вы используете этот шаблон, иначе y будет undefined
.
var y = (function() {
console.log(this); // window
})();
IMO, он такой же, как и третий. Скобки 3-го, включенные в функцию, предназначены только для того, чтобы функция выглядела как одна вещь. Но функциональность обоих одинакова.
var z = function() {
console.log(this); // window
}();
Как и во втором, но вы можете ссылаться на x вне области функций, используя:
(x = function () {
console.log(this); // window
console.log(x); // function x() {}
})();
console.log(x); // function x() {}
Ответ 4
(функция() { 'use strict'; вы можете использовать этот тип
Почему?: Выражение функции IFF-Exited Exited удаляет переменные из глобальной области. Это помогает предотвратить изменения переменных и деклараций функций дольше, чем ожидалось, в глобальной области, что также помогает избежать переменных коллизий.
Почему?: Когда ваш код минимизируется и объединяется в один файл для развертывания на производственный сервер, вы можете столкнуться с переменными и многими глобальными переменными. IIFE защищает вас от обоих из них, предоставляя переменную область для каждого файла.