尽管函数包装,但值在循环中未闭合
Value not closed over in a loop, despite function-wrapping
我有一个正在循环的对象列表;这些对象中的每一个都具有一个属性,该属性是引用CCD_ 1的函数。如果我基于对象创建了一个回调列表,那么为了维护正确的引用,我似乎必须"双包装"依赖于this
的函数。我不明白为什么——有人能解释吗?
function Pokemon(name) {
this.name = name;
this.sayName = function() {
console.log(this.name);
};
}
function runFunctions(arrayOfFunctions) {
for (var i = 0, fn; fn = arrayOfFunctions[i]; i++) {
fn();
}
}
var monsters = [
new Pokemon('Charmander'),
new Pokemon('Squirtle'),
new Pokemon('Bulbasaur')
];
var unclosedCalls = [];
var closedCalls = [];
for (var i = 0, monster; monster = monsters[i]; i++) {
var unclosedCall = (function(m) {
return m.sayName
})(monster);
var closedCall = (function(m) {
return function() {
m.sayName();
}
})(monster);
unclosedCalls.push(unclosedCall);
closedCalls.push(closedCall);
}
console.log('--start')
runFunctions(unclosedCalls); // doesn't work
console.log('----')
runFunctions(closedCalls); // works
console.log('--end')
closedCalls
是双包装回调的列表。
我不明白为什么每次创建unclosedCall
时的m
实际上都不是封闭的。
下面是一个包含我的代码的jsbin:http://jsbin.com/qivilusuje/1/edit?js,控制台,输出
"未关闭"调用的问题在于,返回的函数引用(m.sayName
)会立即与检索函数属性的变量m
解除关联。
函数引用不知道从哪个对象中检索到它,因此当函数最终被调用时,它没有"上下文"——this
将被设置为全局对象,而不是最初将此函数作为属性的对象:
var obj = {
func : function() { console.log(this) }
}
obj.func() // outputs "obj" because a.b() calls "b" with "this" === "a"
var ref = obj.func;
ref(); // outputs "window"
要修复它,您可以让未关闭的调用执行return m.sayName.bind(m)
,尽管到目前为止也不需要IIFE,而且它也可以说:
var unclosedCall = monster.sayName.bind(monster);
相关文章:
- JavaScript/Jquery:一个特殊用途的for循环函数
- 为循环函数中的元素指定单击
- Jquery下一个和上一个按钮循环函数
- 循环函数(Javascript回调帮助)
- 循环函数不起作用
- 使用ajax调用循环函数
- 在Javascript中修改循环函数的参数
- 如何循环函数数组并在单击时一次执行一个
- 设置超时可以保存我的循环函数不被视为无响应
- 具有超时的循环函数
- j查询如何在一系列延迟后循环函数
- 如何将 JavaScript forEach 循环/函数转换为 CoffeeScript
- for 循环函数似乎未运行
- 对于内部循环函数(新手)
- 循环函数会导致它在 javascript 中无响应
- 循环函数
- 如何优化循环函数
- JS拒绝循环函数
- 中断循环函数
- 在 JavaScript 中循环函数可以吗?