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

Javascript 如何使用对象方法更改对象属性,javascript,oop,Javascript,Oop,嗨,我正试图了解javascript oop,遇到了一个问题,我正在构建一个构造函数类,在这个类中我定义了属性,现在我想定义一些改变这些属性的方法,但是当我实例化对象并调用该方法时,控制台告诉我属性未定义。我想这可能与范围有关,我一直在谷歌搜索,但所有的介绍性文章基本上都是一样的 这是代码的简化版本。在我的示例代码中,我希望形状在画布上移动。它自身的对象将拥有控制其运动的方法(目前仅限于此)。当我实例化这个对象时,我调用它的moveRight方法,它应该改变它的xy坐标。然后,每隔一秒钟,我就会

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

这是代码的简化版本。在我的示例代码中,我希望形状在画布上移动。它自身的对象将拥有控制其运动的方法(目前仅限于此)。当我实例化这个对象时,我调用它的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.
有人能告诉我为什么不能从object方法中访问属性吗?我要做什么才能访问它们?谢谢语法中可能缺少一个括号或是我在运行时写的东西。我认为原始代码中没有语法错误,我认为这不是问题所在。

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

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);
  }  

}

这一切都是关于
范围的

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

      }        
   }        
}

内部
setInterval
处理程序
指的是
窗口
。您需要使用闭包:

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);
  }      
}
将上下文绑定到函数:

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);
      }      
    }

当您使用
window.setInterval
setInterval
window.setInterval
的缩写)时,您需要维护对对象的引用

执行回调函数时,
不引用调用的对象<代码>窗口。setInterval在不同的上下文(即
窗口的上下文)中调用回调函数

一种解决方案是使用
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

编辑:

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

JavaScript的
这个
被传闻称为“坏掉的”<代码>窗口。setInterval
是出现混淆的主要示例。始终注意执行“此函数”的上下文。

您有两个错误:

  • 当您嵌套在对象下方的两个级别时,您不能引用
    (其他解决方案向您展示如何使用
    var that=this;
    one level over解决此问题)
  • 您使用大写字母
    F
    编写了函数-改为小写
    请创建一个小提琴,无论如何,你可能想从我的游戏中获得一些想法(对不起,我还没有发表评论)-事实上,这不是范围。(双关语)
    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));
    }