2015-01-29 4 views
0

У меня есть вопрос относительно цепочки областей видимости в javascript. У меня есть следующий код:Цепочка области действия функции - javascript

var num = 10; 
function addFunction(num){ 
    var fun = function(num2) { 
     return num + num2; 
    } 
    num++; 
    return fun; 
} 
console.log(addFunction(5)(5)); 

Я не знаю, почему он будет печатать 11 в консоли. может кто-нибудь мне помочь? i youg, что он будет печатать 15. Хотя мне трудно понять объем функции.

С благодарностью

+1

'num' является параметром' addFunction' и локальна туда. 'Num' в' fun' будет ссылаться на эту (увеличенную) переменную; глобальное 'num' затенено. – Bergi

+0

var num = 10; не действует функция. и функцию addFunction (5) (5). ;/whats happend is: 1) first call addFunction (5) return fun и если num ++ его среднее 5 ++ = 6.-> 2) второй вызов addFunction (5) (5) вызов fun (5) {// и возврат 6 + 5} – miukki

ответ

2

По какой логике он будет печатать 15? Ах я вижу.

Линия

var num = 10; 

не имеет значения. Внутри addFunctionnum - это параметр, который фиксируется анонимной функцией, назначенной fun. К тому времени fun называли, параметр num был увеличен на 1 и стать 6.

+0

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

+0

Это вопрос? Внутри анонимной функции «num» - это «num», ближайший к функциональному коду, который является параметром 'num'' addFunction'. – Igor

+0

@itzikos: Ну, да. Вот как это работает. Область, в которой вызывается функция, никогда не влияла на цепочку областей видимости. Целевая область видимости фиксируется, когда функция * создана *. – Bergi

0

Существует внутренний объект функции F инициализируется fun когда управление приходит к выражению в fun функции. F.[[scope]] установлен в контексте LexicalEnvironment addFunction. Вы можете просто рассмотреть LexicalEnvironment как объект, сохраняющий все переменные со значением в текущей области. Здесь он держит num с его стоимостью. Таким образом, до fun возвращается, num установлено в 6 в F.[[scope]].

Позже, когда вы звоните по fun(5), что происходит за это num извлекается из F.[[scope]], который 6 и fun фактически наречен F.call

Более подробной информации о цепочке областей видимости в JavaScript, есть удивительный пост здесь: http://hujiale.me/2015/01/31/scope-the-most-important-thing-in-javascript/

1

о том, почему вы получили console.log (addFunction (5) (5)) == 11 см. Мой ответ выше.

И

если вы хотите позвонить console.log (AddFunction (5) (5)) и получить 10, вы можете использовать эти решения:

//other solutin 

function tickF(n) { 

var y = function(m) { 
    return f(m+n); 
}, f = arguments.callee; 
y.toString = y.valueOf = function() { 
    return n; 
}; 
return y; 
} 

console.log('no memory leak', String(tickF(1)(2)(3)), String(tickF(1)(2)(3))) 

ответ 6, 6

или с закрытием, но этот solutoin вы не можете позвонить во второй раз, потому что общая переменная не была сброшена после завершения цепочки вызовов:

//chain call fn()()() 
var tick = (function(){ 
    var total = 0; 
    function fnGenerator(arg) { 
    total += arg; 
    return arguments.callee; 
    } 

    fnGenerator.toString = function(){ return total;} 
    return fnGenerator; 

})() 

console.log('memory leak', String(tick(1)(1)), String(tick(1)(1))) 

вы получите ответ н консоль: 2, 4

посмотреть все решения здесь: https://github.com/miukki/es5-bind/blob/master/tick.js

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