我正在查看关于 javascript 闭包的 Mozillas 开发者网站,他们有这个代码示例。
function makeAdder(x){
return function (y) {
console.log(y + " this is y")
console.log(x + " this is x")
return x + y;
}
}
var add10 = makeAdder(10);
console.log(add10(2)); // 12
现在我了解了正在设置的 X 属性,但我不明白 y 的范围是如何受到影响的。我知道它是一个返回函数,但我的大脑开始思考如何在没有引用的情况下设置 y 。有人可以解释吗?
最佳答案
makeAdder
返回一个函数,您可以将 y
参数传递给该函数。它是在调用时设置的,与 x
相反,它是在创建新函数时设置的(在调用 makeAdder
时)。
对于这个例子来说,输出等同于写了:
function add10(y) {
return 10 + y;
}
console.log(add10(2)); // 12
这里没有发生什么新鲜事。示例代码主要是试图说明正在为x
创建一个闭包。
所以 makeAdder
在这里的名字很贴切:当您将 10 传递给它时,它会为您提供一个函数,该函数会将您传递给 的所有内容加 10那个新功能。
var add10 = makeAdder(10);
var add20 = makeAdder(20);
console.log(add10(1) + add20(1)); // 32
当然,为了添加的目的,只拥有一个接受两个参数并添加它们的函数可能会更容易。但这不是添加的教训,而是闭包的教训。
现实世界的场景可能是这样的:
var buttons = document.getElementsByClassName('myButton');
for(var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
alert('You clicked button ' + i);
};
}
在上面的代码中,i
将在单击任何按钮之前迭代整个集合。因此,无论 buttons.length
是什么,所有 按钮都会发出警报。相反,您可以执行以下操作:
var makeAlert = function(x) {
return function() {
alert('You clicked button ' + x);
};
};
for(var i = 0; i < buttons.length; i++) {
buttons[i].onclick = makeAlert(i);
}
这里的区别是 i
在点击按钮时不被使用(这将在整个迭代之后),但它在 迭代期间使用,在我
会的时候
每个按钮都有不同的值。
与创建变量 makeAlert
不同,您经常会看到这种类型的代码被编写为匿名函数,并立即被调用。下面的代码基本上等同于上面的代码:
for(var i = 0; i < buttons.length; i++) {
buttons[i].onclick = (function(x) {
return function() {
alert('You clicked button ' + x);
};
})(i);
}
关于javascript - 在 javascript 中返回函数,理解作用域和闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8487768/