0

こんにちは、私は javascript oop に頭を悩ませようとしていますが、問題が発生しています。コンストラクター クラスを構築しています。クラスでプロパティを定義します。これらのプロパティを変更するメソッドを定義したいと思いますが、オブジェクトをインスタンス化するときプロパティが未定義であることをコンソールが教えてくれるメソッドを呼び出します。これはスコープと関係があるのではないかと思います。Google でいろいろ調べてみましたが、紹介記事は基本的にすべて同じです。

コードの簡略化されたバージョンを示します。私のコード例では、形状をキャンバス上で移動させたいと考えています。オブジェクト自体には、その動きを制御するメソッドがあります(今のところ)。オブジェクトをインスタンス化するとき、xy 座標を変更する moveRight メソッドを呼び出します。次に、毎秒、オブジェクトの 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(setIntervalは の省略形です)を使用する場合window.setInterval、オブジェクトへの参照を維持する必要があります。

コールバック関数が実行されるとき、呼び出し元thisのオブジェクトを参照しません。別のコンテキスト、つまり のコンテキストでコールバック関数を呼び出します。setIntervalwindow.setIntervalwindow

1 つの解決策は、 を使用すること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) に変更する必要があります。

編集:

Function.prototype.bindES5 環境でも使用できます。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

2 つのエラーがあります。

  1. オブジェクトの 2 レベル下にネストされている場合は参照できません(他のソリューションでは、 1 レベル上thisを使用して回避する方法を示しています)。var that = this;
  2. 大文字を使用して関数を書きFました - 小文字に変更してください!
于 2013-09-29T18:52:53.320 に答える