关闭 - 常识?

时间:2016-05-13 17:23:41

标签: javascript closures

MDN的A re-introduction to JavaScript文章结束时讨论了闭包:

  

在另一个函数内定义的函数可以访问外部函数   函数的变量。这里唯一的区别是外层   功能已经恢复,因此常识似乎在决定   它的局部变量不再存在。

文章继续讨论范围对象和范围链等。听起来非常复杂。然而,通过他们的示例脚本,我认为没有理由为什么常识会失败?

function makeAdder(a) {
  return function(b) {
    return a + b;
  };
}
var x = makeAdder(5);
var y = makeAdder(20);

x(6); // returns 11
y(7); // returns 27

所以,设置x = to makeAdder with argument,5:

x = function(b) {return 5 + b;};

所以当我们现在用参数6调用x时,我们有

function(6) {return 5 + 6;};

返回11。

我想我的问题是:我错过了什么吗?闭包似乎很简单。为什么人们会对这个概念感到不知所措?

2 个答案:

答案 0 :(得分:1)

  

我想我的问题是:我错过了什么吗?闭包似乎很简单。为什么人们会对这个概念感到不知所措?

不,你没有遗漏任何东西。闭包很简单。你甚至不得不问那些声称自己很复杂的人 - 甚至要写关于这个主题的书籍 - 为什么他们认为他们是。

可能被认为是复杂的是采用一种利用这个简单概念的设计思维。

答案 1 :(得分:0)

我发现DOM元素创建循环最能显示问题。请注意,此代码打印的按钮具有正确的i值,但单击时会显示5,因为当时未创建捕获i的新闭包。



for(var i = 0;  i < 5; i++) {
  var btn = document.createElement("button");
  var t = document.createTextNode(i); 
  btn.appendChild(t); 
  btn.onclick=function(){ alert(i) }
  document.body.appendChild(btn);
}
&#13;
&#13;
&#13;

此代码创建一个新的闭包,它将提醒正确的值。

&#13;
&#13;
for(var i = 0;  i < 5; i++) {
  var btn = document.createElement("button");
  var t = document.createTextNode(i); 
  btn.appendChild(t); 
  btn.onclick=onClick(i);
  document.body.appendChild(btn);
}

function onClick(i) { 
   return function() { alert(i) }
}
&#13;
&#13;
&#13;