2015-09-01 2 views
2

Я немного смущен.JS - функция самостоятельного вызова против обычной функции

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

Но в этом аспекте функции сам ссылающаяся, кажется, действует одинаково для регулярной функции, как в этом примере:

function xx(){ 

    var x="variable"; 
    //logs into console 
    console.log(x); 
    } 

xx(); 
//logs undefined 
console.log(x); 

Таким образом, единственная реальная разница с регулярной функцией и сам призывом является «я ссылающаяся» частью, что мне просто не нужно запускать функцию вручную после объявления?

+0

Ну, одна дополнительная вещь, которую самоосуществляющаяся часть дает вам, что даже' xx' Безразлично» t «загрязнить» пространство имен. –

ответ

0

Самозапускаемые функции являются нормальными функциями, но не имеют имени. Это делает их невозможными для вызова, кроме как сразу после объявления, что фактически делает их одноразовой функцией, которая навсегда скрыта от другого кода.

Как вы отмечаете, форма

function foo() { 
    console.log("foo"); 
} 
foo() 

и

(function() { 
    console.log("foo"); 
})() 

ведут себя одинаково.

Однако первая форма с function foo() {... создает именованную функцию, которая живет в этой области действия до тех пор, пока область действия не будет уничтожена. Для глобального масштаба это никогда не произойдет, оставив foo действительным и вызываемым идентификатором для любого другого кода в вашем приложении.

Это означает, что в любое время, кто-то может сделать

foo() 

и либо инициализировать модуль еще раз или, возможно, получить дескриптор к новой копии модуля.

В лучшем случае это может привести к путанице и дублированию состояния. В худшем случае, в зависимости от того, как структурирован ваш IIFE, они могут быть в состоянии копаться в скрытом состоянии и начать манипулировать им так, как вы этого не ожидаете.

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

+0

'(function foo() {return 'bar'})()' -> они все равно могут иметь имя. – royhowie

+0

ssube, вы объединяете самопроизвольные и анонимные функции. – SeanKendle

+0

@SeanKendle Функции самоисполнения с целью скрытия области (о которой спрашивает OP) гораздо менее полезны для имени. – ssube

1

«Функция самозапускания» - это имя для общей идиомы JavaScript. На самом деле это не функция; это немедленное выполнение функции. Вы можете назвать это IIFE для «непосредственно вызванного выражения функции», если это помогает.

(function() { // Anonymous function expression 
    // IIFE! 
})(); // Invocation happens here with the()! 
var f = (function() { // Still anonymous 
    // Almost immediately invoked function expression! 
}); 

f(); // Invocation happens here! 
var f = (function f() { // Not anonymous – now called “f” 
    // Almost immediately invoked function expression! 
}); 

f(); // Invocation happens here! 
function f() { // Not anonymous 
    // Almost immediately invoked function *declaration* – not an expression! 
} 

f(); // Invocation happens here! 
0

// defined at `window` 
 
function xx() { 
 

 
    var x = "variable"; 
 
    //logs into console 
 
    console.log(x); 
 
} 
 

 
xx(); 
 
// not defined at `window` 
 
(function yy() { 
 

 
    var y = "variable"; 
 
    //logs into console 
 
    console.log("y:",y); 
 
    // `window["yy"]` : `undefined` 
 
    console.log("yy:", yy, "window['yy']:?", window["yy"]); 
 
}()); 
 

 
console.log("xx", xx, window["xx"]); 
 
try { 
 
    console.log("yy:", yy, window["yy"]); 
 
} catch (e) { 
 
    console.log("yy:", e) 
 
} 
 
try { 
 
    console.log("x:", x); 
 
} catch (e) { 
 
    console.log("x:", e) 
 
}

+0

@ user3667832 См. Http://benalman.com/news/2010/11/immediately-invoked-function-expression/ – guest271314

1

Они должны спутал IIFE остроумие h "self-invoking function".

Вот то, что Бен Alman писал:

Что случилось с

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

Что такое выражение с выражением немедленного вызова? Это выражение функции, которое вызывается немедленно. Точно так же, как название приведет вас к вере.

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

// This is a self-executing function. It's a function that executes (or 
    // invokes) itself, recursively: 

    function foo() { foo(); } 

    // This is a self-executing anonymous function. Because it has no 
    // identifier, it must use the the `arguments.callee` property (which 
    // specifies the currently executing function) to execute itself. 

    var foo = function() { arguments.callee(); }; 

    // This *might* be a self-executing anonymous function, but only while the 
    // `foo` identifier actually references it. If you were to change `foo` to 
    // something else, you'd have a "used-to-self-execute" anonymous function. 

    var foo = function() { foo(); }; 

    // Some people call this a "self-executing anonymous function" even though 
    // it's not self-executing, because it doesn't invoke itself. It is 
    // immediately invoked, however. 

    (function(){ /* code */ }()); 

    // Adding an identifier to a function expression (thus creating a named 
    // function expression) can be extremely helpful when debugging. Once named, 
    // however, the function is no longer anonymous. 

    (function foo(){ /* code */ }()); 

    // IIFEs can also be self-executing, although this is, perhaps, not the most 
    // useful pattern. 

    (function(){ arguments.callee(); }()); 
    (function foo(){ foo(); }()); 

    // One last thing to note: this will cause an error in BlackBerry 5, because 
    // inside a named function expression, that name is undefined. Awesome, huh? 

    (function foo(){ foo(); }()); 

Источник: http://benalman.com/news/2010/11/immediately-invoked-function-expression/