Javascript中的循环,闭包和addEventListener

时间:2015-01-17 09:33:49

标签: javascript

我很抱歉没有那么具体的标题,因为我的英语不够好,无法在标题中清楚地描述这种情况。

我有这样的代码:

var e = document.getElementsByClassName( "test" );
var myFunc = function( e ) { 
  e = e + 1; 
};

for ( var i = 0, l = e.length; i < l; i++ ) {
    var t = e[ i ];
    var j = 0;
    (function( n, num ){
        num = 0;
        n.addEventListener("click", function() {
          myFunc( num );
          console.log( num )
        });
    }( t, j ));
}

我的目的是让变量j的值增加,但每次点击j=0后我仍然会得到.test

Demo

1 个答案:

答案 0 :(得分:2)

您的问题是JavaScript不会通过引用传递原始值(如数字),而是通过值传递。 myFunc函数必须返回一些东西,你不能指定它的参数来改变“外部”值。

这是一种更现代的方法,基于合理的假设,支持getElementsByClassName()的浏览器也支持Array.prototype.forEach()

以下每个HTML元素创建一个带num的闭包。

var elems = document.getElementsByClassName("test"),
    myFunc = function(e) { 
        return e += 1; 
    };

[].slice.call(elems).forEach(function (elem) {
    var num = 0;
    elem.addEventListener("click", function () {
        num = myFunc(num);
        this.textContent = this.textContent.replace(/\d*$/, num);
    });
});
<button class="test">Test 0</button>
<button class="test">Test 0</button>
<button class="test">Test 0</button>


Javascript 通过引用传递对象,因此稍作修改就可以了:

var elems = document.getElementsByClassName("test"),
    myFunc = function(properties) { 
        properties.num += 1; 
    };

[].slice.call(elems).forEach(function (elem) {
    var properties = {
            num: 0
        };
    elem.addEventListener("click", function () {
        myFunc(properties);
        this.textContent = this.textContent.replace(/\d*$/, properties.num);
    });
});
<button class="test">Test 0</button>
<button class="test">Test 0</button>
<button class="test">Test 0</button>