Непосредственные функции JavaScript

Стоян Стефанов говорит в шаблонах JavasScript, что: «вам нужна немедленная функция, чтобы обернуть весь ваш код в его локальную область, а не передавать какие-либо переменные в глобальную область», стр. 70.

Вот его пример

(function() {
    var days = ['Sun','Mon'];
    // ...
    // ...
    alert(msg);
}());

Но, конечно, поскольку дни определены как var, это будет просто функциональная область? Единственным преимуществом немедленной функции является то, что функция вызывается немедленно. Преимущество в размахе отсутствует. Исправить?


person dublintech    schedule 13.11.2012    source источник
comment
и ты не увидишь, что варс снаружи   -  person Eric Frick    schedule 13.11.2012
comment
Если бы он не находился внутри замыкания выше, это была бы глобальная переменная. (область действия будет окном, т.е. то же самое, что и объявление без var) Не уверен, что понимаю, о чем вы спрашиваете...   -  person Snuffleupagus    schedule 13.11.2012
comment
Нет, как вы сказали, days будет в области действия функции, а не в глобальной. Это преимущество в масштабе.   -  person I Hate Lazy    schedule 13.11.2012
comment
ИМХО, вы неправильно интерпретируете его комментарий. Дело не столько в том, что в вашем коде есть плюсы (хотя они и есть, но не в этом дело). Основная причина в том, что другие фрагменты Javascript на том же сайте будут иметь дополнительный уровень защиты от любых ошибок, которые вы могли допустить.   -  person Chuck Kollars    schedule 03.06.2014


Ответы (8)


Речь идет не о немедленно выполняемой функции, а об обычной функции; на самом деле это почти ничего не имеет отношения.

Единственной целью немедленно вызываемой функции-обертки является область видимости переменных, локальных для функции-обертки.

(function() {
    // This variable is only available within this function's scope
    var thisIsTemp = "a";

    // ...
}());

console.log(thisIsTemp); // undefined        

vs:

// This variable is available globally
var thisIsTemp = "a";

// ...

console.log(thisIsTemp); // "a"
person SReject    schedule 13.11.2012
comment
Я думаю, что это лучший ответ. Это не тот случай, когда немедленная вмещающая функция отличается от обычной вмещающей функции. Это непосредственная функция, а не какая-либо объемлющая функция. Просто ванильный JavaScript. - person dublintech; 13.11.2012

Наличие вашей переменной days в области действия функции — это именно смысл этого примера. Без немедленно вызываемой функции все переменные (days, msg) были бы глобальными переменными и загрязняли бы глобальное пространство имен.

person lanzz    schedule 13.11.2012
comment
Какая? Как days будет в глобальной области видимости, если она определена с помощью var внутри функции? - person Vivin Paliath; 13.11.2012
comment
Попробуйте перечитать мой ответ. Без немедленно вызываемой функции переменные были бы глобальными. - person lanzz; 13.11.2012
comment
@lanzz Угу, извини, я слишком быстро прочитал. Виноват! Я думал, вы подразумеваете, что без непосредственного вызова все внутри функции будет в глобальной области видимости. Ошибка чтения-понимания. - person Vivin Paliath; 13.11.2012

Технически это правильно (нет выгоды от области видимости, потому что функция выполняется немедленно; обычная скучная функция также сделала бы то же самое), но не забывайте, что

  1. у вас есть код, который вы хотите запустить прямо сейчас
  2. вы не хотите, чтобы этот код пропускал имена в текущую область

Таким образом, функция создается из-за #2, но она также вызывается немедленно из-за #1.

person Jon    schedule 13.11.2012

«вам нужна немедленная функция, чтобы обернуть весь ваш код в его локальную область, а не передавать какие-либо переменные в глобальную область»

Это неправда. (или по крайней мере спорно)

Я думаю, что ОП спрашивал: «Вам нужна немедленная функция для создания локальной области видимости или вы можете просто использовать обычную область действия функции?» Я согласен с OP, что функция И немедленная функция скроет переменную days в своей области. Чтобы проверить, является ли переменная глобальной, (в консоли) вы можете проверить, определена ли она в window.

Немедленная функция:

(function() {
    var days = ['Sun','Mon'];
    // ...
    // ...
    alert(msg);
}());
window.days; // undefined

Нормальная функция:

var func = function() {
    var days = ['Sun','Mon'];
    // ...
    // ...
    alert(msg);
};
window.days; // undefined
Object.prototype.toString.call(window.func); // "[object Function]"

Как видите, days не является глобальным в обоих случаях. Он скрыт или приватен в пределах области действия функции. Однако во втором примере я создал глобальную переменную func. Но это доказывает, что вам не нужна непосредственная функция для создания локальной области видимости.

PS: Я никогда не читал эту книгу. Я уверен, что автор умен и знает, о чем говорит, но в данном случае он недостаточно конкретен. Или, может быть, нам нужно больше контекста, окружающего цитату, чтобы полностью понять ее.

person Jess    schedule 03.02.2014

Идея того, что var находится внутри функции, заключается в следующем:

не допускать утечки каких-либо переменных в глобальную область видимости

Дело в том, что в этом случае дни не будут видны вне функции и если вы попытаетесь написать в консоли console.log(days) то получите дни не определены

Это сделано потому, что вы никогда не знаете, кто еще будет использовать ваш код позже, и может быть, он переопределит ваши переменные дни.

person Salvador Dali    schedule 13.11.2012

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

var days = ['Sun','Mon'];
// ...
// ...
alert(msg);
person Vivin Paliath    schedule 13.11.2012

В JavaScript локальные переменные имеют область действия функции, а не области действия блока. Например, в опубликованном вами коде days фактически является локальным для функции:

(function() {
  var days = ['Sun','Mon'];
  // ...
  // ...
  alert(msg);
}());

Но если бы вы сказали следующее в глобальном масштабе:

// ...
{ 
    var days = ['Sun','Mon'];
    // ...
    // ...
}
alert(msg);

days станет глобальной переменной (видимой всем во внешней области видимости), даже если она определена внутри блока. Имеет ли это смысл?

person Justin Ethier    schedule 13.11.2012

у меня тот же вопрос
я думал, что единственное преимущество непосредственной функции в том, что она должна использоваться с анонимной функцией
когда мы используем анонимную функцию, это означает, что она никогда не будет повторно использована; без имени, как вы могли вызвать его?
так что лучше сделать его непосредственной функцией .
автор не дал ясности !

var func = function() {
var days = ['Sun','Mon'];
// ...
// ...
alert(msg);
func();

дни также находятся в локальной области func, а не в глобальной переменной

person xcchcaptain    schedule 26.05.2014