0

こんにちは、これは JavaScript アプリケーションを作成しようとする最初の試みであるため、それを使用して OOP コードを作成するのは初めてです。

次のコードは、コンソールでエラーなしで実行されます。

// Main file for the application
$(document).ready( function()
{
    var app = new application;
    setInterval( app.run, 50 );

});

function application()
{
   var canvas = Raphael(10,0,400,400);
   this.molecule = new molecule( new Vec2(50,50),new Vec2(1,0),canvas );
   this.molecule.update(10);

   this.run = function()
    {

    }
}

ただし、次のコードは機能しません。

// Main file for the application
$(document).ready( function()
{
    var app = new application;
    setInterval( app.run, 50 );

});

function application()
{
   var canvas = Raphael(10,0,400,400);
   this.molecule = new molecule( new Vec2(50,50),new Vec2(1,0),canvas );

   this.run = function()
    {
        this.molecule.update(10);
    }
}

コンソールに次のエラーが表示されます。

Uncaught TypeError: Object function molecule( pos,vel,canvas )
    {
        this.radius = 5;
        this.color = "red";

        this.canvas = canvas;

        this.pos = pos;
        this.vel = vel;

        this.circle = canvas.circle( this.pos.x,this.pos.y,this.radius );

        this.circle.attr("fill", this.color );


    } has no method 'update' 

これは、分子オブジェクトを含むソース ファイルです。

    // This 'class' handles a molecule, including movement and drawing.

    function molecule( pos,vel,canvas )
    {
        this.radius = 5;
        this.color = "red";

        this.canvas = canvas;

        this.pos = pos;
        this.vel = vel;

        this.circle = canvas.circle( this.pos.x,this.pos.y,this.radius );

        this.circle.attr("fill", this.color );


    }

 // Updates the molecule
    molecule.prototype.update = function( deltaTime )
    {
        this.pos += this.vel * deltaTime;
        this.setPosition(this.pos);
    }

    // Accepts a Vec2
    molecule.prototype.setPosition = function( pos )
    {
        this.circle.translate( pos.x-this.pos.x, pos.y-this.pos.y );
    }    

大量のコードを投稿して申し訳ありませんが、最初のコードは機能するのに 2 番目のコードは機能しない理由がわかりません。誰かが私のためにそれに光を当てることができますか? どうもありがとう。

4

2 に答える 2

1

よくある間違いです。ここで何が起こっているかを確認するには、JavaScript をよく理解している必要があります。問題は次の行です。

setInterval( app.run, 50 );

これにより、適切なコンテキストなしでapp.runインターバルが終了したときに呼び出されます。がコンテキストとして呼び出されるようにするには、次のようなものが必要です。thisrunappthis

setInterval( function() {
    app.run();
}, 50 );

または最新の JavaScript を使用する (最新のブラウザーのみ):

setInterval( app.run.bind(app), 50 );

JavaScript の関数のthisコンテキストは、関数の呼び出し方法によって決まります。基本的に、呼び出されたオブジェクトによって決定されます。たとえば、app.run()では、runメソッドが on で呼び出されapp、期待どおりに動作します。ただし、少し異なるシナリオでは

var fn = app.run;
fn();

関数はオブジェクトに対して呼び出されないためthis、設定されず、予期しない結果が発生します。これはまさにあなたの場合に起こっていることです。解決策は、任意のオブジェクトで呼び出すことができる関数を渡すようにし、その関数呼び出しrunを正しいオブジェクトで行うことです。

于 2013-02-16T20:38:21.013 に答える
0

runからメソッドを切り離しましたapp。それらをまとめる関数を渡します。

setTimeout(function() { app.run(); }, 50);

thisinの値がオブジェクト.run()になりappます。


また、オブジェクトrunごとに新しいメソッドを作成する必要もありません。を装着application()できます。runapplication.prototype

function application() {
   var canvas = Raphael(10,0,400,400);
   this.molecule = new molecule( new Vec2(50,50),new Vec2(1,0),canvas );
   this.molecule.update(10);
}

application.prototype.run =  function() {
    this.molecule.update(10);
}

ただし、コンストラクターを保持した場合run、オブジェクトを参照する変数を閉じることができるため、安全に切り離すことができます。

function application() {
   var canvas = Raphael(10,0,400,400);
   this.molecule = new molecule( new Vec2(50,50),new Vec2(1,0),canvas );
   this.molecule.update(10);

   var self = this;

   this.run = function() {
       self.molecule.update(10);
   }
}

setTimeout(app.run, 50)
于 2013-02-16T20:37:53.153 に答える