access variables(object) outside function within a for loop
本问题已经有最佳答案,请猛点这里访问。
我的问题可能听起来像一个关于关闭的问题但它确实有一些区别。
1 2 3 4 5 6 7 8 9 10 11 12 | 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'函数指向正确的对象?
您可以使用立即调用的函数表达式将闭包分解为外部人员,例如:
1 2 3 4 5 6 | button.onclick = (function (p) { return function (e) { console.log('printing name'); console.log(p.name); }; }(person)); |
顺便说一句,javascript区分大小写,因此您要分配给onclick属性,而不是onClick。
您似乎也在使用或假设DOM规范的扩展,例如
1 | document.createElement('div', {id: 'mainDiv'}); |
这不是标准的JavaScript,似乎假设主机方法的扩展。
1 2 3 4 5 6 7 8 9 10 11 | 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到onclick。
代码中的闭包需要捕获新上下文中的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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/