2012-02-14 1 views
5

誰かがこれを私に説明できますか?Javascriptで完全に作成される前に変数を使用しているようですが、これは機能します - なぜですか?

var diagramImage = new Kinetic.Shape(function() { 
    var context = this.getContext(); 
    context.beginPath(); 
    context.lineWidth = 1; 
    //This is crazy tricks. It's part of the KineticJS demo website, but how am I able to assign diagramImage.color here? 
    context.strokeStyle = diagramImage.color; 

    var lastVertice = polygon.Vertices[polygon.Vertices.length - 1]; 

    context.moveTo(lastVertice.X, lastVertice.Y); 

    for (var i = 0; i < polygon.Vertices.length; i++) { 
     var vertice = polygon.Vertices[i]; 
     context.lineTo(vertice.X, vertice.Y); 
    } 

    context.stroke(); 
    context.closePath(); 
}); 

diagramImageはキネティックコンストラクタ戻るまで存在していないように私には思えるが、私はできる午前(とする必要があるように見える)コンテキストのstrokeStylediagramImageに色割り当てる - diagramImageが作成される前に?なぜこれは機能しますか?

EDIT:フルコード:

function DrawPolygon(diagramLayer, polygon) { 
    var diagramImage = new Kinetic.Shape(function() { 
     var context = this.getContext(); 
     context.beginPath(); 
     context.lineWidth = 2; 
     //This is crazy tricks. It's part of the KineticJS demo website, but how am I able to assign diagramImage.color here? 
     context.strokeStyle = diagramImage.color; 

     var lastVertice = polygon.Vertices[polygon.Vertices.length - 1]; 

     context.moveTo(lastVertice.X, lastVertice.Y); 

     for (var i = 0; i < polygon.Vertices.length; i++) { 
      var vertice = polygon.Vertices[i]; 
      context.lineTo(vertice.X, vertice.Y); 
     } 

     context.stroke(); 
     context.closePath(); 
    }); 

    diagramImage.color = "red"; 

    diagramImage.on("mouseover", function() { 
     this.color = "green"; 
     diagramLayer.draw(); 
    }); 

    diagramImage.on("mouseout", function() { 
     this.color = "red"; 
     diagramLayer.draw(); 
    }); 

    diagramLayer.add(diagramImage); 
    planViewStage.add(diagramLayer); 
} 
+0

あなたが含むこのコード部分の前に 'diagramImage'が既に定義されていますか? – ziesemer

+0

いいえこのチュートリアルを参照してください:http://www.html5canvastutorials.com/labs/html5-canvas-interactive-flower/変数 'c​​enter'で同じことを行います –

+0

あなたが投稿できる追加コードはありますか?あなたの主張? – shanabus

答えて

8

Kinetic.Shapeコンストラクタに渡されるクロージャ/関数内でどこにdiagramImage.colorを呼び出しているので。この関数は、コンストラクタによって作成された新しいインスタンスがdiagramImageに割り当てられるまで、コンストラクタによって呼び出されず/実行されません。

var MyObject = function(f){ 
    this.myFunc = f; // f is executed sometime later... 
}; 
MyObject.prototype.execute = function(){ 
    this.myFunc(); 
}; 

var myObjInst = new MyObject(function(){ 
    console.log("myObjInst:", myObjInst); 
}); 
myObjInst.execute(); 

Twisolが指摘したように、これは代わりにthisを使用することによって改善することができます。ここでは

は、より良い何が起こっているのかを説明することができる最小限の例です。たとえば:APIによって文書化されない限り

(function(){ 
    var MyObject = function(f){ 
    this.myFunc = f; // f is executed sometime later... 
    }; 
    MyObject.prototype.execute = function(){ 
    this.myFunc(); 
    }; 

    var myObjInst = new MyObject(function(){ 
    console.log("myObjInst:", this); 
    }); 
    myObjInst.execute(); 
})(); 

しかし、クリスが述べたように、 - thisがコールバック中にKinetic.Shapeを参照するという保証はありません - ので、まだこれらの2の方が良いかもしれここdiagramImageを使い続けますオプション。

要するに、これはJavaScriptの最高のAPI /例/使用ではないと私は考えています。これは対処しなければならないJavaScriptのニュアンスではありません。確かに、これらのニュアンスが必要な場合はそこにありますが、そうする必要はありません。

+0

このコードをもっともっと作る方法はありますか...直感的ですか?それとも、これは私が愛することを学ばなければならないJavascriptのニュアンスですか? :) –

+0

ソース(文字通り)[ここ](http://www.kineticjs.com/download/kinetic-v3.7.3.js)。 'drawFunc'は' Kinetic.Shape'でも 'Kinetic.Node'でも呼び出されませんが、' drawFunc'と呼ばれ、プロパティとして保持されているということが伝えられます。 – Twisol

+1

@SeanAnderson:はい、 'diagramImage'ではなく' this'を関数で使用します。これは 'drawFunc' *が呼び出された場所で正しいオブジェクトを' this'として提供するので、ここでは大丈夫です。 – Twisol

0

私はこの記事がそれを説明するのに役立つかもしれないと思う - http://www.quirksmode.org/js/associative.html

連想配列に特にセクション。この書き込みでは、javascriptのオブジェクトも連想配列とみなされています。

したがって、diagramImage.strokeStyleが明示的に定義されていない場合でも、diagramImage['strokeStyle']を参照できます。

これは役に立ちますか?

1

これは興味深い構成です。何が起きているかは、次のように見えます。

  • diagramImageは、宣言だけで何かが割り当てられる前の参照です。これを視覚化するには、var diagramImageが自己によって前の行にあったと想像してください。
  • Kinetic.Shapeは、後で使用するコンストラクタ引数の1つとして、その無名関数をコールバックします。
  • コールバックはKinetic.Shapeオブジェクトを参照します。おそらく、thisが後で言及するもの(this.getContext()の使用によるもの)を記述する契約があり、それはKinetic.Shapeオブジェクトではないと思われます。
  • diagramImageが参考になるので、参照が使用されるまでには、新しいKinetic.Shapeが割り当てられます。この目的に使用することをお勧めします。

原則として、ローカル変数を使用して現在のコールバックをコールバックで利用できるようにする通常のパターンと同じです。

var self = this; 
$('myelement').click(function(){ self.hi = true; }); 

ここで、後で使用できる変数は現在のオブジェクトではなく、前記オブジェクトのメンバーです。

+0

http://ja.wikipedia.org/wiki/Closure_(computer_science) –

関連する問題