JS范围/闭包如何通过论证

时间:2016-11-01 20:34:38

标签: javascript scope closures

有人可以解释为什么在以下函数中,我能够将参数传递给嵌套函数吗?我的理解是它必须对闭包和范围做一些事情(我认为我对它有一个很好的理解),但我似乎可以理解这个参数究竟是如何传递的。

以下功能分别输出1,2。但是返回语句 doThis()如何获得" a "的参数/参数?我无法确定访问/传递的位置/方式。

function doSomething(){
  var b = 1;
  return function doThis(a){
        console.log(b);//1
        console.log(a);//2
  }
}
var exec = doSomething();
exec(2);

2 个答案:

答案 0 :(得分:4)

函数doSomething()返回另一个函数,所以当你执行

var exec = doSomething();

您可以将exec视为包含以下功能

function doThis(a){ // <- takes an argument
    console.log(1); // comes from the b argument in the outer scope
    console.log(a); // not set yet
}

因此,当您致电exec(2)时,您实际上正在使用参数doThis()来调用2,该参数将成为a的值。

这是一个略微简化的版本。为了进行扩展,doSomething()函数被描述为关闭 doThis(),创建闭包。相反,函数doThis() 关闭关闭。封闭本身只是围绕功能的有限状态:

function doSomething(){ // --> defines the closure
  var b = 1; // variable only visible within doSomething()
  return function doThis(a){ //<--> function has access to everything in doSomething(). Also defines another closure
        console.log(b); // --> accesses the OUTER scope
        console.log(a); // <-- comes from the INNER scope
  } // <-- end INNER scope
} // --> end OUTER scope

当您执行doSomething()时,返回的结果仍然保留对其中范围的访问权限,这就是doThis()可以访问值b的原因 - 它只是可以访问它。它与你的工作方式类似

var foo = 40;

function bar(value) {
  return foo + value;
}

console.log(bar(2));

只有在这种情况下,任何其他代码都可以访问foo因为它是一个全局变量,所以如果你在另一个函数中执行foo = 100,那将改变bar()的输出。闭包可以防止 中的代码从闭包中到达

答案 1 :(得分:1)

当您指定var exec = doSomething();时,exec基本上是写作:

 var doSomething = function(a) {
        console.log(b);
        console.log(a);
  }

它成了它自己的功能。所以像2一样传入exec(2)就像任何普通函数一样,只是因为闭包它有变量b