如何使用对象方法更改对象属性

时间:2013-09-29 18:43:10

标签: javascript oop

嗨我试图让我的脑袋围绕javascript oop并遇到问题,我正在构建一个构造函数类,在类我定义属性现在我想定义一些方法来改变那些属性,但是当我instanciate对象并调用方法,consol告诉我属性是未定义的。我想这可能与范围有关,我一直在寻找谷歌很多,但所有介绍性文章基本相同。

这是一个简化版本的代码。在我的示例代码中,我希望一个形状在画布上移动。它自己的对象将拥有控制其移动的方法(现在正好)。当我实例化对象时,我调用它的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.

有人能告诉我为什么无法从对象方法中访问这些属性吗?以及我必须做什么才能访问它们?谢谢...语法中可能缺少一个括号或我在运行中写的东西我不认为原始代码中的语法错误,我不认为这就是问题。

5 个答案:

答案 0 :(得分:1)

当您使用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,而不是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)); } 的对象)。

this

JavaScript的window.setInterval被传闻称为“破碎”。 {{1}}是出现混淆的主要示例。始终要注意“this-functions”执行的上下文。

答案 1 :(得分: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);
  }  

}

答案 2 :(得分: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

      }        
   }        
}

答案 3 :(得分: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);
      }      
    }

A fiddle.

答案 4 :(得分:0)

您有两个错误:

  1. 当您嵌套在对象下方两级时,您无法引用this(其他解决方案向您展示如何使用上面一级var that = this;处理它)
  2. 您使用大写F编写了函数 - 更改为小写!