2013-09-29 132 views
0

嗨我試圖讓我的頭繞過javascript oop和我遇到了問題,我正在構建一個構造函數類,我在類中定義屬性現在我想定義一些方法改變這些屬性,但是當我實例化對象並調用方法時,控制檯告訴我屬性是未定義的。我想這可能與範圍有關,我一直在尋找谷歌很多,但所有介紹性文章基本相同。如何使用對象方法更改對象屬性

繼承人的簡化版本的代碼。在我的示例代碼中,我想要一個形狀在畫布上移動。它自身的對象將擁有控制其移動的方法(現在正好)。當我實例化對象時,我調用它的moveRight方法,它應該改變它的xy座標。 ,然後每隔我把它rendor屏幕在一個單獨的函數調用的對象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. 

誰能告訴我,爲什麼這些特性是從內無法訪問對象方法?以及我必須做些什麼來訪問它們?謝謝......有可能是一個支架在語法中丟失或我在飛行中寫了一些東西,我不認爲這是原代碼中的語法錯誤,我不認爲這是問題所在。

+0

請創建一個小提琴,無論如何,你可能想從我的遊戲中採取一些想法(對不起,我沒有評論它) - http://borisute.com/geshem/2013/mkeller/adventure.html –

回答

1

當您使用window.setIntervalsetIntervalwindow.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); 
} 

此外,您需要更改 「功能」 的 「F」,以小寫字母f(function,不Function)。

編輯:

您也可以在ES5環境中使用Function.prototype.bind。它返回一個函數,該函數將其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)); 
} 

JavaScript的this一直有傳言稱,提及到的「破」。 window.setInterval混淆出現的最佳示例。始終注意「本功能」執行的環境。

0

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

} 
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 

     }   
    }   
} 
+0

其實,這不是範圍。 (雙關語意) – SLaks

0

setInterval處理thiswindow。你要麼需要使用封閉:

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.

0

你有兩個錯誤:

  1. 你不能指當你的對象下嵌套的兩個級別this(其他的解決方案向您展示如何使用上述var that = this;一個層次解決它)
  2. 你寫的函數使用大寫F - 改成小寫!
相關問題