0

嗨,我试图了解 javascript oop 并遇到问题,我正在构建一个构造函数类,在类中我定义属性现在我想定义一些改变这些属性的方法,但是当我实例化对象时并调用控制台告诉我属性未定义的方法。我想这可能与范围有关,我一直在 google 周围搜索,但所有介绍性文章都基本相同。

这是代码的简化版本。在我的示例代码中,我想要一个形状在画布上移动。它自己的对象将具有控制其运动的方法(现在只是)。当我实例化对象时,我调用它的 moveRight 方法,该方法应该改变它的 xy 坐标。然后每一秒我都会在一个单独的函数中将它渲染到屏幕上,该函数调用对象 x 和 y 属性

//这里我定义对象

function Mechanoid(){

//object properties

this.life=100;
this.x=500;
this.y=200;
this.anArray=new Array(0, 0); //can i create an array like this? i know it works when called from   outside the object



//object methods

this.moveAround=function(){ 

   var clock=setInterval(Function ()  {
       this.x=this.x+1;   //console log says undefined
       this.y=this.y+1;

       this.anArray[0]=this.x;  //console says cannot read propety of null
       this.anArray[1]=this.y;
        },1000);
  }  

}


 //then instanciate  

 var mech=new Mechanoid;
 mech.moveAround();   // calls method to change object properties


//A request for the x any y coordinates of mech object will be called in a render function where it
//will be drawn to the canvas.

谁能告诉我为什么无法从对象方法中访问这些属性?我必须做什么才能访问它们?谢谢...语法中可能缺少括号或我在运行中编写的内容我认为原始代码中没有语法错误,我认为这不是问题所在。

4

5 回答 5

2

当您使用window.setInterval(setIntervalwindow.setInterval) 的简写时,您需要维护对您的对象的引用。

当你的回调函数被执行时,this并不指setInterval调用来自的对象。window.setInterval在不同的上下文中调用您的回调函数,即window.

一种解决方案是使用var self = this;. 虽然值this根据上下文而变化,但self它是一个任意变量,它维护对您分配给它的任何对象的引用。

this.moveAround = function () { 
    var self = this;
    var clock = setInterval(function () {
        self.x = self.x + 1;
        self.y = self.y + 1;
        self.anArray[0] = self.x;
        self.anArray[1] = self.y;
    }, 1000);
}

此外,您需要将“Function”中的“F”更改为小写 f ( function, not Function)。

编辑:

您也可以Function.prototype.bind在 ES5 环境中使用。它返回一个函数,该函数将其this设置为一个对象(在本例中为调用的对象moveAround)。

this.moveAround = function () {
    setInterval(function () {
        this.x = this.x + 1;
        this.y = this.y + 1;
        this.anArray[0] = this.x;
        this.anArray[1] = this.y;
    }.bind(this));
}

JavaScriptthis被传闻称为“损坏的”。window.setInterval是产生混淆的一个典型例子。始终注意“this-functions”执行的上下文。

于 2013-09-29T18:52:29.580 回答
0

您丢失了函数中的上下文 ( this) 。setInterval尝试 :

this.moveAround=function(){ 

   var that = this;
   var clock=setInterval(function ()  {
       that.x=that.x+1;   
       that.y=that.y+1;

       that.anArray[0]=that.x;  
       that.anArray[1]=that.y;
        },1000);
  }  

}
于 2013-09-29T18:46:47.290 回答
0

这就是全部scope

function Mechanoid() {

    var self = this; // cache this

    // bla bla

    this.moveAround = function() {

        var clock = setInterval(function () {
            self.x = self.x + 1;   // no longer undefined
            self.y = self.y + 1;

            // continue this way

      }        
   }        
}
于 2013-09-29T18:46:50.797 回答
0

内部setInterval处理程序this是指window. 您要么需要使用闭包:

this.moveAround=function(){ 
   var self = this;
   var clock=setInterval(function ()  {
       self.x=self.x+1;   //console log says undefined
       self.y=self.y+1;

       self.anArray[0]=self.x;  //console says cannot read propety of null
       self.anArray[1]=self.y;
        }, 1000);
  }      
}

bind运行的上下文:

this.moveAround=function(){ 
       var clock=setInterval(function ()  {
           this.x=this.x+1;   //console log says undefined
           this.y=this.y+1;

           this.anArray[0]=this.x;  //console says cannot read propety of null
           this.anArray[1]=this.y;
            }.bind(this), 1000);
      }      
    }

一个小提琴。

于 2013-09-29T18:47:17.537 回答
0

你有两个错误:

  1. this当您嵌套在对象下方的两个级别时,您无法引用(其他解决方案向您展示如何使用var that = this;上面的一个级别来解决它)
  2. 你用大写写了函数F- 改为小写!
于 2013-09-29T18:52:53.320 回答