2

我的一个javascript代码有一点问题。这是代码

//assume array is an array containing strings and myDiv, some div in my doc
for(var i in array) {
    var myString = array[i];
    var a = document.createElement('a');
    a.innerHTML = myString;
    a.addEventListener("click", function() {myFunc(myString)}, false);
    myDiv.appendChild(a)
}
function myFunc(s) {alert(s);}

但是,由于字符串在 JavaScript 中是通过引用传递的,所以array当我单击相关链接时,我总是看到 my 的最后一个字符串a。因此,我的问题是“我如何myString通过价值传递?”。感谢您的帮助 !菲尔

4

3 回答 3

2

在 Javascript 中,原始变量不是通过引用传递的。

这是经典的“闭包内调用循环变量”问题。

这是该问题的一种常用解决方案:

for (var i = 0, n = array.length; i < n; ++i) {
    var myString = array[i];
    var a = document.createElement('a');
    a.innerHTML = myString;
    a.addEventListener("click", make_callback(myString), false);
    myDiv.appendChild(a)
}

function make_callback(s) {
     return function() {
         alert(s);
     }
}

请注意,这并不是特别有效的内存,因为它为数组中的每个元素创建了一个新的函数范围。

更好的解决方案可能是将变量数据实际存储在元素上(即作为新属性)并在回调中检索它。事实上,您已经将该字符串存储在.innerHTML属性中,因此您可以读取它,然后利用委托在元素的父级上仅注册一个处理程序:

for (var i = 0, n = array.length; i < n; ++i) {
    var a = document.createElement('a');
    a.innerHTML = array[i];
    myDiv.appendChild(a)
}

myDiv.addEventListener('click', function(ev) {
    alert(ev.target.innerHTML);
}, false);
于 2012-08-13T15:13:06.077 回答
2

您应该在事件处理程序周围添加一个闭包:

循环内的 JavaScript 闭包——简单实用的示例

a.addEventListener("click", function (s) {
    return function () {
        alert(s)
    };
}(myString), false);

此外,您不应for...in在数组上使用循环。

于 2012-08-13T15:13:36.857 回答
-1

试试这个:我认为最好不要练习使用 for...in 迭代数组

for(var i=0; i<array.length;i++) {
    var myString = array[i];
    var a = document.createElement('a');
    a.innerHTML = myString;
    a.addEventListener("click", function() {myFunc(myString)}, false);
    myDiv.appendChild(a)
}
function myFunc(s) {alert(s);}
于 2012-08-13T15:13:55.323 回答