0

this.SOME_MEMBER をメソッドに渡そうとしていますが、同じメンバーとして通過しません。以下のコードは、私がやろうとしていることをもう少し理解できるはずです。

function App()
{
    this.canvas = new Object();
}

App.prototype.createCanvas = function(obj, width, height)
{
    obj = document.createElement('canvas');
    obj.setAttribute('width', width);
    obj.setAttribute('height', height);

    log(obj == this.canvas); //false
    log(this.canvas == app.canvas); //true 
                                    //it's clear that this refers to app

    //so why doesn't obj refers to this.canvas? 
    //how do i get obj to equal this.canvas?
}

App.prototype.init = function()
{
    this.createCanvas(this.canvas, 800, 600);
    log(this.canvas.width); //undefined
}

var app = new App();
app.init();

今、私は単に次のことを行うことができることを理解しています:

function App()
{
    this.canvas = new Object();
}

App.prototype.createCanvas = function(width, height)
{
    this.canvas = document.createElement('canvas');
    this.canvas.setAttribute('width', width);
    this.canvas.setAttribute('height', height);
}

App.prototype.init = function()
{
    this.createCanvas(800, 600);
    log(this.canvas.width); //800
}

var app = new App();
app.init();

これはほとんどのアプリケーションで機能しますが、変数の名前を this.canvas に制限しています。最終的には、メソッドをもう少し柔軟にする必要があります。

document.createElement 関数と element.setAttribute 関数を単なる例として使用していることに注意してください。それらは、変数 obj を変更するものに置き換えることができます。


では、「this.canvas」が引数として使用されている場合、どうなるでしょうか。どうすればやりたいことを達成できますか?

前もって感謝します!

4

2 に答える 2

2

では、obj が this.canvas を参照しないのはなぜですか?

関数で最初に行ったのは、代わりに別の値を与えるためです。

App.prototype.createCanvas = function(obj, width, height)
{
    obj = document.createElement('canvas');
//  ^------------------------------------------ here
    obj.setAttribute('width', width);
    obj.setAttribute('height', height);

    log(obj == this.canvas); //false
    log(this.canvas == app.canvas); //true 
                                    //it's clear that this refers to app

    //so why doesn't obj refers to this.canvas? 
    //how do i get obj to equal this.canvas?
}

JavaScript は純粋に値渡し言語です。obj引数には、渡したがあります (これはthis.canvas、呼び出し時に指定した値であるためです) 。プロパティobjへの参照ではありません。this.canvasやりたいことをやりたいように実行するには、this.canvas(プロパティ) を参照渡しする必要がありますが、これは JavaScript ではできません。(ただし、以下を参照してください。)

今、私は単に次のことを行うことができることを理解しています:

(コード省略)

これはほとんどのアプリケーションで機能しますが、変数の名前はthis.canvas. 最終的には、メソッドをもう少し柔軟にする必要があります。

これはやや奇妙な要件です (確実にすべてのAppインスタンスが にキャンバスを持っている必要があります) が、オブジェクトのどのプロパティにキャンバスを配置するかcanvasを指定できるようにしたい場合は、次のようにします。createCanvas

JavaScript は、オブジェクト プロパティを参照する 2 つの方法をサポートしています。リテラルを使用するドット表記法 ( this.canvas) と、文字列を使用するブラケット表記法 ( this["canvas"]) です。後者の場合、文字列はリテラルである必要はなく、変数参照を含む任意の式の結果にすることができます。

だからあなたは次のようにcreateCanvasなります:

App.prototype.createCanvas = function(propName, width, height)
{
    // Create the canvas
    var obj = document.createElement('canvas');
    obj.setAttribute('width', width);
    obj.setAttribute('height', height);

    // Save that canvas to the given property
    this[propName] = obj;
}

そして、あなたはそれを次のように呼びます:

App.prototype.init = function()
{
    this.createCanvas("canvas", 800, 600);
}

そうは言っても、呼び出し元のコードがキャンバスを好きな場所に配置できるように、キャンバスをcreateCanvas 返す方がより直接的です。

App.prototype.createCanvas = function(width, height)
{
    // Create the canvas
    var obj = document.createElement('canvas');
    obj.setAttribute('width', width);
    obj.setAttribute('height', height);
    return obj;
}

それから

App.prototype.init = function()
{
    this.canvas = this.createCanvas(800, 600);
}

補足: が関数式であっても、最後にx = ...a が必要な場合は、セミコロンがありません。たとえば、は最後にa が必要です。;..App.prototype.init = ...;

App.prototype.init = function()
{
    this.canvas = this.createCanvas(800, 600);
}; // <=== Here

自動セミコロン挿入の恐ろしさのため、構文エラーは発生しませんが、これに頼らないことを強くお勧めします。それを余裕)。常に正しいセミコロンを含めることで、長期的には時間を節約できます。

于 2012-12-15T13:13:40.583 に答える
0

あなたのライン、

obj = document.createElement('canvas');

メソッドに渡された obj 変数をオーバーライドし、createCanvasそれを完全に新しいオブジェクトとして設定します。変数の割り当てにより、以前の参照が中断され、新しいオブジェクトへの新しい参照が作成されます。obj 変数は、別のオブジェクトへの参照です。これを使用して、参照されるオブジェクトを完全に異なるオブジェクトに変更することはできません。

メソッドを呼び出すか、プロパティを変更して obj 変数を操作すると、それらはすべて元のオブジェクトに作用します。そのため、代わりにオブジェクトをメソッドに渡すこともthisできます (ただし、別のスコープで関数を呼び出す予定がない限り、これは少し無意味に思えます)。

于 2012-12-15T13:21:12.750 に答える