2011-12-23 7 views
0

JS +キャンバスで実験しています。 私の最小限のアプリケーションの「目標」は、キャンバス上の任意の場所をクリックし、描画ボタンを押して、クリックした場所を四角で描画することです。javascript型の問題:未知の型エラー:オブジェクト0にメソッド 'draw'がありません

OOバックグラウンドから来ています...私はOOを使用しようとしました。これは、jsでは完全に把握できません。

が、基本的に私は、カスタムスクエアオブジェクトiの配列にユーザーがクリックするたびに追加

function Square(l, w, x, y) { 

    this.length = l; 
    this.width = w; 
    this.posx = x - l/2; 
    this.posy = y - w/2; 

    //test 
    //ctx.fillStyle = "rgb(20,0,0)"; 
    //ctx.fillRect(this.posx,this.posy,this.length,this.width); 


    this.draw = function() { 

     ctx.fillStyle = "rgb(20,0,0)"; 
     ctx.fillRect(this.posx,this.posy,this.length,this.width); 

    } 
} 

を持っている...ここ は私がキャンバス上をクリックしたときのイベントハンドラです。

function addTo(evt) { 

    pos = getMousePos(evt); 
    var sq = new Square(50, 50, pos.x, pos.y); 
    list.push(sq); 

    output.innerText = "("+sq.posx+","+sq.posy+")"; 
} 

ここでは、四角形を描く場所です(試行)。私は、同様のエラーがそのオブジェクトの変数にアクセスしようとしてもらう

Uncaught TypeError: Object 0 has no method 'draw' 

function renderStack() { 

    //alert(list); 
    canvas.width = canvas.width; 
    for(var o in list) o.draw(); 

} 

が、これは誤りです。 リストに追加した後、jsはどのタイプのものなのか忘れてしまったようです。 - 配列を印刷すると[オブジェクトオブジェクト]がいっぱいです。

ありがとうございます。

+0

トピックをオフにしますが、 'draw'メソッドをコンストラクタから取り出して、' prototype'に一度置きます。 'Square.prototype.draw = func ...' –

+0

ありがとう、JSの新しい、特にオブジェクトのための良いリソース。私は矛盾するものをいくつか読んだ。 –

答えて

4
for(var o in list) 

oは、配列のインデックス(またはプロパティ)です。そのインデックスに格納されているものにはlist[o]でアクセスします。

しかし、配列の場合、for-inよりもアルニタックのようにループがforである方が良いでしょう。

更新:あなたはすべてのプロパティをループする必要がある場合に

について-で使用されるべきです。配列はオブジェクトであるため、インデックスとプロパティを持ちます。したがって、for-inはすべてのインデックスとプロパティを反復処理します。 for-inはオブジェクトの方が優れています。

var obj = { p1: 1, p2: 2}; 

for(var prop in obj) { 
    //... 
} 
+0

@ cream-corn:更新を参照してください。これは、なぜfor-in配列のためのヒントを与えるかもしれない:http://jsfiddle.net/BGurung/5tbdh/。 –

+1

@ cream-corn: 'for-in'が列挙に使用されます。 JavaScriptでは、すべての列挙可能なプロパティをヒットし、人々は配列を拡張したいので、配列では使用しないことをお勧めします。したがって、すべての列挙可能なプロパティが必要なときに 'for-in'を使用します。インデックスの繰り返しが必要なときは 'for'を使います。しかし、これはあなたの問題の原因ではありませんでした。問題は 'key'を' value'を得るのではなく、 'key'で' .draw() 'を呼び出すことでした。あなたが選んだ答えには、誤解を招くような情報が含まれています。この答えはより良いです。 –

+0

はい、私は今これと私の方法のエラーを認識しています。迅速な返信のためのすべてのおかげで:) –

5

for ... in ...はあなたに、オブジェクトのキーなくその内容を与えます。

だから、アレイ上のあなたはインデックス保存された要素の名、他の列挙のプロパティの両方を受け取ることになります。

代わりに、あなたが使用する必要があります。

for (var i = 0; i < list.length; ++i) { 
    list[i].draw(); 
} 
+1

配列はオブジェクトです。直接の間違いは、値の代わりにkey(String)のメソッドを呼び出すことでした。あなたが正しいと思っても、 'for'ステートメントを使う方が良いです。 –

+1

@amnotiamのテキストが修正されました - 私は急いでそれを書いていました。更新のために – Alnitak

+0

+1。 –

関連する問題