javascript - 在闭包中保留变量内容时遇到问题

标签 javascript loops object scope closures

<分区>

(这个问题与 thisthis 有关,但那里的答案并没有帮助我弄清楚我的情况出了什么问题。)

我正在尝试创建一个可点击元素数组,其中每个元素都绑定(bind)到某个对象的单独实例。

我在这里尽可能地简化了我正在为这个问题处理的真实代码:

//----------
// 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 = ... 我会创建一个新的上下文/范围/但是它会为每个匿名 click() 回调调用我正在创建的函数——这样当我点击其中一个对象时,相应 SomeObject 的适当数量是 alert()ed 而不是最后一个的数量SomeObject 循环从数组中获取。

有人可以向我解释为什么此代码片段无法按预期工作,以及需要更改哪些内容才能使代码正常运行吗?

最佳答案

要在 JavaScript 中创建闭包作用域,您需要调用一个函数。在 JavaScript 中,我们还可以在声明函数后立即调用它们。他们被称为immediately invoked function expressions

这样您就可以在 IIFE 的范围内保留您的 xy 值。

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))
  }
}

Working codepen

此外,这是人们在尝试将 JavaScript 编写为基于类的语言时遇到的一个大问题。我会尝试从更多 functional perspective 研究编写 JS

关于javascript - 在闭包中保留变量内容时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31753474/

相关文章:

Javascript 将值传递给另一个 JS 类和 HTML 页面

javascript - 尝试纠正 JSLint 投诉时未定义 jQuery 值 : "Don' t make functions within a loop"

python - 如何将 python 中 for 循环的输出写入 csv 格式的文件?

loops - 如何让音频循环一定次数?

javascript - 如何一次打印对象中的所有属性/值。 JS

android - 过滤列表 Activity

javascript - 嵌套的 javascript 对象

javascript - Nodejs + Express 总是返回index.html

javascript - 处理 React Redux 应用程序中的异步错误

java - 嵌套循环 - 第三个?