我对javascript中的范围链有疑问。 我有以下代码:
var num = 10;
function addFunction(num){
var fun = function(num2) {
return num + num2;
}
num++;
return fun;
}
console.log(addFunction(5)(5));
我不确定为什么它会在控制台中打印11。 有人可以帮助我吗? 我认为它会打印15.虽然我很难理解功能的范围。
由于
答案 0 :(得分:2)
它打印15的逻辑是什么?啊,我明白了。
该行
var num = 10;
无关紧要。内部addFunction
num
是由分配给fun
的匿名函数捕获的参数变量。在调用fun
时,参数num
已增加1并变为6。
答案 1 :(得分: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
答案 2 :(得分:0)
当控件到达F
函数表达式时,有fun
初始化的内部函数对象fun
。 F.[[scope]]
设置为addFunction
执行上下文的LexicalEnvironment。您可以简单地将LexicalEnvironment
视为一个对象,使所有变量在当前范围内保持值。这会使num
保持其价值。因此,在返回fun
之前,num
中的F.[[scope]]
设置为6。
稍后当您通过fun(5)
致电时,num
后面发生的事件F.[[scope]]
是从fun
检索到的,其中F.call
实际上是{{1}} {{1}}
有关JavaScript中范围链的更多信息,这里有一篇很棒的帖子: http://hujiale.me/2015/01/31/scope-the-most-important-thing-in-javascript/