返回意外号码

时间:2017-02-09 00:55:36

标签: javascript html5 oop

这是控制我角色的代码。 "控制"是按钮类的名称。我使用for循环来声明添加触摸事件监听器。我可以在触摸时改变颜色。索引0上的元素用于左转,索引1上的元素用于跳转。

问题: 当我用控制台登录触摸事件功能检查i变量的数量时,它返回15.我只有4个元素。 15与我的案件不符。

我的问题是i变量如何返回15?

var getControl = {
    buts : document.getElementsByClassName("control"),

    build : function(world){
        for(i = 0; i < 4; i++){

            this.buts[i].addEventListener("touchstart",function(e){
                console.log(getControl.temp);
                e.preventDefault();
                this.style.backgroundColor = "green";
                console.log(i);
                switch(i){
                    case 0:
                        misc[0].left();
                        console.log("left");
                        break;
                    case 1:
                        misc[0].jump();
                        break;
                    case 2:
                        misc[0].right();
                        break;
                    case 3:

                        break;
                };
            },false);
            this.buts[i].addEventListener("touchend",function(e){
                e.preventDefault();
                this.style.backgroundColor = "red";
            },false);
            this.buts[i].addEventListener("touchleave",function(e){
                e.preventDefault();
                this.style.backgroundColor = "red";
            },false);

2 个答案:

答案 0 :(得分:1)

  1. 首先for(i = 0; i < 4; i++)会将i声明为全局变量,因此(假设您为代码中的所有循环执行此操作)i将具有该值它来自上次执行的for循环。
  2. 对于此代码和未来代码中的所有for循环,您应该做的是声明索引i(或j或...),如下所示:< / p>

    for(var i = 0; i < 4; i++) {
    
    1. for循环在整个迭代过程中具有相同的范围,因此闭包将被搞砸。因为所有事件侦听器都会获得对同一i的引用,所以当它们被调用时,它们会尝试查看i具有的值(即使您纠正了问题 1. < / strong>,i将没有您期望的值,因为在将对它的引用传递给事件侦听器后它将被更改。通过不断递增来改变它)。您需要的是一种为数组的每个项创建唯一范围的机制。您可以尝试使用此solution,或使用for的替代方案,例如forEach(与链接中的解决方案大致相似)。
    2. 所以这个:

      for(i = 0; i < 4; i++) {
          this.buts[i].addEventListener("touchstart", function(e) {
              // ...
      

      应该替换为:

      // since buts is an array-like object we can't use forEach directly but we could call it like this
      Array.prototype.forEach.call(this.buts, function(but, i) {
          but.addEventListener("touchstart", function(e) {
              // you can use i here and it will work
          });
          // ...
          // but is equivalent to this.buts[i]
      });
      

答案 1 :(得分:0)

在你的for循环中你有

i=0

这将i声明为全局变量,因此它可能会增加或分配到其他位置。全局命名空间很危险。

尝试在函数范围内创建一个变量,如下所示:

var i = 0