功能范围链 - javascript

时间:2015-01-29 16:58:26

标签: javascript

我对javascript中的范围链有疑问。 我有以下代码:

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

我不确定为什么它会在控制台中打印11。 有人可以帮助我吗? 我认为它会打印15.虽然我很难理解功能的范围。

由于

3 个答案:

答案 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初始化的内部函数对象funF.[[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/