【发布时间】:2015-08-14 20:48:42
【问题描述】:
在有关闭包的文章中,您经常会看到在循环内部创建闭包,使用自调用函数将迭代器变量传递给返回的函数表达式,以便在迭代器变量的值周围创建闭包。自调用函数被调用,而不是在循环结束后调用它的值。这是一个例子:
var func = [];
for (var i = 0; i < 3; i++)
{
func.push((function(j){ return function(){ console.log(j); }; })(i));
}
// Logs
// 0
// 1
// 2
// to the console
for (var i = 0; i < func.length; i++)
{
func[i]();
}
根据我的简单实验,这种技术适用于数字和字符串。但是,相同的技术不适用于纯 JavaScript 对象。如果将对象传递给自调用函数并在函数表达式中引用,则对封闭对象的更改在函数表达式中可见,因为传递给自调用函数的值是对对象的引用,而不是对象的副本对象,就像数字和字符串一样。
我可以理解为什么这种技术不适用于存储对象的变量,但我不明白为什么这种技术应该适用于数字和字符串,它们的原型链以 Object 终止。
这是否意味着字符串和数字只是解释器以不同方式处理的对象的特殊情况,还是我有一个基本的误解?
【问题讨论】:
-
当您写“相同的技术不适用于纯 JavaScript 对象”时,您的意思并不清楚。它以什么方式“不起作用”?出乎意料的会发生什么?
-
@Pointy - 好问题。我的意思是,当一个对象在每次循环迭代中发生变异时,这些变异会反映在函数表达式已关闭的对象中。这正是我对一个对象的期望。我不明白(或不明白)为什么像数字和字符串这样的原型链以 Object 结尾的东西的行为方式不同。
-
好的,那是因为你一遍又一遍地将完全相同的对象的引用推送到数组上。它实际上与按值传递与按引用传递无关。对象的“值”是对该对象的引用;这是在 JavaScript 中操作对象的唯一方法。
-
正确。我的问题是,例如,为什么数字和字符串的行为方式不同,因为我误解了数字和字符串也是对象。如果我为变量 myNum 分配一个数字,那么 myNum.__proto__.__proto__.constructor === Object.然而 Object.getPrototypeOf(myNum) 引发了一个错误,抱怨 myNum 不是一个对象。 myNum 怎么可能不是一个对象,却有一个 .__proto__ 属性和一个终止于 Object 的原型链?
标签: javascript loops closures