我的问题可能听起来像一个关于关闭的问题,但确实有一些不同。
var people = [{name: 'john', age: 20},
{name: 'james', age: 25},
{name: 'ryan', age: 19}];
var mainDiv = document.createElement('div', {id: 'mainDiv'});
for (var i = 0; i < people.length; i++) {
var button = document.createElement('button', {}, mainDiv);
var person = people[i];
button.onClick = function (e) {
console.log('printing name');
console.log(person.name);
};
}
这只是我编写的一个例子。由于person变量指向people数组的最后一个对象,因此在for循环结束时,它总是在单击按钮时打印出最后一个元素。然而,我想要实现的是在单击每个按钮时打印出每个相应人的姓名。我该怎么做才能让内部'onClick'函数指向正确的对象?
答案 0 :(得分:1)
for (var i = 0; i < people.length; i++) {
var button = document.createElement('button', {}, mainDiv);
var person = people[i];
var clickfunc=function(name){return function(e){
console.log('printing name');
console.log(name);
}}
button.onclick = clickfunc(person.name);
}
你是对的,这不是一个典型的闭包函数,而是一个常见的误用闭包,其中变量应该是预先绑定的。
调用clickfunc函数时,person.name将传递给调用堆栈,其值为AT THE TIME OF CALLING。函数本身返回另一个函数,因此在实际单击按钮之前,您不会调用它。
我还纠正了onClick to onclick。
答案 1 :(得分:1)
您可以使用立即调用的函数表达式将闭包分解为外部 person ,例如:
button.onclick = (function (p) {
return function (e) {
console.log('printing name');
console.log(p.name);
};
}(person));
顺便提一下,javascript区分大小写,因此您要分配到 onclick 属性,而不是 onClick 。
您似乎也在使用或承担DOM规范的扩展,例如
document.createElement('div', {id: 'mainDiv'});
这不是标准的javascript,似乎假设主机方法的扩展。
答案 2 :(得分:0)
代码中的闭包需要捕获新上下文中的person
对象。这可以通过创建一个返回函数(内部)并将参数传递给该外部函数的新函数(外部)来完成。此外,最好使用attachEvent
或addEventListener
而非onclick
附加活动。对maindDiv.onclick
的其他调用将覆盖元素上的任何事件处理程序。
var people = [{name: 'john', age: 20},
{name: 'james', age: 25},
{name: 'ryan', age: 19}];
var mainDiv = document.createElement('div', {id: 'mainDiv'});
for (var i = 0; i < people.length; i++) {
var button = document.createElement('button', {}, mainDiv);
var person = people[i];
attachEvent(button, "click",bindClickEvent(person));
}
//Outer function
function bindClickEvent(person){
//inner function retains context of outer function
return function(){
console.log('printing name');
console.log(person.name);
};
}
function attachEvent(elem, event, func){
if(elem.attachEvent){
elem.attachEvent("on" + event, func);
}else{
elem.addEventListener(event, func);
}
}
JS小提琴: http://jsfiddle.net/vD5B7/1/