在闭包中保留变量内容时遇到问题
Having issues preserving variable contents in closure
(这个问题与 this and this 有关,但那里的答案并没有帮助我弄清楚我的情况出了什么问题。)
我正在尝试创建一个可点击元素数组,其中每个元素都绑定到某个对象的单独实例。
对于这个问题,我在这里尽可能地简化了我正在处理的真实代码:
//----------
// Setup part
// SomeObject just holds a number
var SomeObject = function(number) {
this.number = number;
this.getNumber = function() {
return this.number;
};
};
// contains SomeObject(1) through SomeObject(9)
var someArrayContainingObjects = [];
for(var i=1; i<=9; i++)
{
someArrayContainingObjects.push(new SomeObject(i));
}
//----------
// Problem part
for(var y=0; y<3; y++)
{
for(var x=0; x<3; x++)
{
var obj = someArrayContainingObjects[y*3 + x]; // Creating new variable in the loop every time explicitly with var statement?
$("body").append(
$("<button />")
.text("Should output ("+obj.getNumber()+")")
.click(function() {
alert(obj.getNumber()); // Will always be 9
})
);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
我想通过在循环中显式使用 var obj = ...
我会创建一个新的 context/scope/however 它会为我正在创建的每个匿名 click()
回调函数调用 - 所以当我点击其中一个对象,相应 SomeObject
的适当数量是 alert()
ed,并不总是循环从数组中获取的最后一个 SomeObject
的数量。
有人可以向我解释为什么此代码片段无法按预期工作,以及要更改哪些内容才能使代码正常运行吗?
要在 JavaScript 中创建闭包作用域,您需要调用一个函数。在 JavaScript 中,我们还可以在您声明函数后立即调用它们。他们被称为immediately invoked function expressions
这样您就可以在 IIFE 的范围内保留您的 x
和 y
值。
for(var y=0; y<3; y++) {
for(var x=0; x<3; x++) {
(function (x, y) {
var obj = someArrayContainingObjects[y * 3 + x]
$("body").append(
$("<button />")
.text("Should output ("+obj.getNumber()+")")
.click(function() {
alert(obj.getNumber())
})
)
}(x, y))
}
}
此外,这是人们在尝试编写 JavaScript 时遇到的一个大问题,就好像它是一种基于 class 的语言一样。我会尝试从更 functional perspective
的角度研究编写 JS
(这个问题与 this and this 有关,但那里的答案并没有帮助我弄清楚我的情况出了什么问题。)
我正在尝试创建一个可点击元素数组,其中每个元素都绑定到某个对象的单独实例。
对于这个问题,我在这里尽可能地简化了我正在处理的真实代码:
//----------
// Setup part
// SomeObject just holds a number
var SomeObject = function(number) {
this.number = number;
this.getNumber = function() {
return this.number;
};
};
// contains SomeObject(1) through SomeObject(9)
var someArrayContainingObjects = [];
for(var i=1; i<=9; i++)
{
someArrayContainingObjects.push(new SomeObject(i));
}
//----------
// Problem part
for(var y=0; y<3; y++)
{
for(var x=0; x<3; x++)
{
var obj = someArrayContainingObjects[y*3 + x]; // Creating new variable in the loop every time explicitly with var statement?
$("body").append(
$("<button />")
.text("Should output ("+obj.getNumber()+")")
.click(function() {
alert(obj.getNumber()); // Will always be 9
})
);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
我想通过在循环中显式使用 var obj = ...
我会创建一个新的 context/scope/however 它会为我正在创建的每个匿名 click()
回调函数调用 - 所以当我点击其中一个对象,相应 SomeObject
的适当数量是 alert()
ed,并不总是循环从数组中获取的最后一个 SomeObject
的数量。
有人可以向我解释为什么此代码片段无法按预期工作,以及要更改哪些内容才能使代码正常运行吗?
要在 JavaScript 中创建闭包作用域,您需要调用一个函数。在 JavaScript 中,我们还可以在您声明函数后立即调用它们。他们被称为immediately invoked function expressions
这样您就可以在 IIFE 的范围内保留您的 x
和 y
值。
for(var y=0; y<3; y++) {
for(var x=0; x<3; x++) {
(function (x, y) {
var obj = someArrayContainingObjects[y * 3 + x]
$("body").append(
$("<button />")
.text("Should output ("+obj.getNumber()+")")
.click(function() {
alert(obj.getNumber())
})
)
}(x, y))
}
}
此外,这是人们在尝试编写 JavaScript 时遇到的一个大问题,就好像它是一种基于 class 的语言一样。我会尝试从更 functional perspective
的角度研究编写 JS