2016-04-27 3 views
1

Попытка выяснить, почему функция self invoking сохраняет личное значение, а другой тип - нет.Функция самозапуска не сохраняет личное значение

ли увеличить значение

var a = function(){ 
    var myval=10; 
    return function(){ 
      return myval++; 
    } 
}(); 
console.log(a()); 
console.log(a()); 
console.log(a()); 

Выход: 10,11,12

в то время как этот код не увеличивает значение

var a = function(){ 
    var myval=10; 
    return function(){ 
      return myval++; 
    } 
}; 
console.log(a()()); 
console.log(a()()); 
console.log(a()()); 

Выход: 10,10,10

+0

Я должен уйти прямо сейчас, но с головы до головы. Я считаю, что это потому, что IIFE в # 1 создает область для myval, и каждый экземпляр вызова внутренних функций указывает на myval. Второй создает новую область с новым myval для каждого вывода console.log, поэтому он многократно возвращает 10. – timolawl

+0

Любопытно, почему 10? Если вы измените (в не вызываемой self-функции) 'myval ++' на 'myval + 1' или' ++ myval', он вернет 11 (всегда, как и когда функция не вызывается самостоятельно). –

+0

это означает, что первый метод создает только один экземпляр внешней функции, а второй метод создает 3 экземпляра внешней функции? – LilRazi

ответ

3

В вашем первом примере a является экземпляром закрытия, который неоднократно вызывается в вашем console.log s:

console.log(a()); // <-- a is a closure, invoked once 
console.log(a()); // <-- the same closure, invoked the second time 
console.log(a()); // <-- the same closure, invoked a third time 

Однако, в вашем втором примере это внешняя функция, которая получает неоднократно призывала в своих console.log с:

console.log(a()()); // <-- a is the outer, returning a new closure, invoked once 
console.log(a()()); // <-- a is the outer, returning a new closure, invoked once 
console.log(a()()); // <-- a is the outer, returning a new closure, invoked once 

Так что вы делаете в вашем втором примере, каждый раз заново создает новое закрытие, вместо повторного вызова того же экземпляра закрытия, что и в вашем первом примере.

2

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

Ваш первый пример более эквивалентно:

var a = function(){ 
    var myval=10; 
    return function(){ 
      return myval++; 
    } 
}; 

var b = a(); 

console.log(b()); 
console.log(b()); 
console.log(b()); 

В то время как ваш второй один, как:

var a = function(){ 
    var myval=10; 
    return function(){ 
      return myval++; 
    } 
}; 

var b = a(); 
var c = a(); 
var d = a(); 

console.log(b()); 
console.log(c()); 
console.log(d()); 

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

+0

Мне также нравится использовать «как если бы», чтобы объяснить запутанный код. +1 – Barmar

Смежные вопросы