7

これが JavaScript で行われているのをよく見てきましたが、その理由を見つけたのは覚えていますが、答えは思い出せません。

スコープと「クラス」の外で呼び出される関数に関係があると思いますが、なぜこれを行うのでしょうか(できれば例を概説します):

function myClass ()
{
    var self = this;

    //...

    this.myArray = [];

    this.myFunc = function () { alert(self.myArray.length); };
}
4

5 に答える 5

5

クロージャーの一部として変数にラッチするため。

例えば:

MyClass.prototype.doStuff = function(){
  this.foundItems = [];
  var self = this;
  this.myString.replace(/.../,function(){
    // `this` is actually the `window` inside this callback
    // so we need to use `self` to invoke another method on our instance object
    self.foundItems.push( self.doOtherStuff() );
  });
};

あなたが書いた特定の例は、期待される方法でメソッドを呼び出す場合、クロージャを必要としません:

function Foo(){
  this.array = [];
  this.myFunc = function(){
    return this.array;
  }
}
var foo = new Foo;
foo.myFunc(); // []

ただし、次のように「分割」することは可能です。

var f2 = foo.myFunc;
f2(); // undefined, since `this` was the window

一方、クロージャーを使用するコードは、この種のばかげたことに対して安全です。

于 2012-05-30T15:08:48.650 に答える
2

「これ」は、現在の「オブジェクト」を指します。JavaScriptについて話すとき、「this」式がコンテキストごとに評価されるという事実に力があります。たとえば、メソッドが別のオブジェクトコンテキストで実行される場合、「this」値はそれぞれ変更されます。

于 2012-05-30T15:10:17.147 に答える
1

別の関数内に関数を作成するthisと、内部関数がグローバル ウィンドウ オブジェクトに設定されます。の値を保存する変数を作成するとthis

var that = this;

that次に、内部関数内で外部関数を参照するために使用できます。

于 2012-05-30T15:12:56.060 に答える
0

私は本当にそれをしたいとは思わない:

  • インスタンスが作成されるたびに、関数の「コピー」も作成されます。したがって、5 つのインスタンスは、関数の 5 つの「コピー」を作成します。
  • 関数のその「コピー」は、その特定のインスタンスにのみ関連する環境にバインドされるため、一般的に使用することはできません。つまり、拡張クラスは、おそらく使用されていない親クラスのインスタンスにのみ関連するメソッドを取得します。
  • 特にこれらのインライン関数をネストし始めると、インデントが手に負えなくなります
  • プロトタイプ定義で検索するだけでなく、他の関数内の関数を探す必要があります

別の方法:

function MyClass() {
    this.myArray = [];
    this.myFunc = this.myFunc.bind(this); //The "blueprint" in the prototype is not affected, the instance gets its own bound version.
                                           //This means the one in prototype can be inherited or used generically anywhere else as well
}

MyClass.prototype = {

    myFunc: function() { //My func is neatly listed in the prototype and can use `this` normally
        alert(this.myArray.length);
    },

    constructor: MyClass
};


var myObj = new MyClass();

document.addEventListener( "click", myObj.myFunc ); //Will now work as you "expect" it to work

いくつかの欠点:

  • バインドされた各関数は新しい関数であるため、インスタンスごとに、1 つの新しい関数が毎回作成されます。
  • コンストラクター内のすべての呼び出しを書き出す定型文.bindですが、次のようなヘルパーで軽減できます_.bindAll
于 2012-05-30T15:53:40.003 に答える
0

他のユーザーが投稿したいくつかの回答に加えて、これに変数セットを作成すると、オブジェクトにアクセスせずに変数を再利用できます。

次のようなことをするのと似ています:

var myElement = document.getElementById('someElement');

そして、必要に応じて、document.getElementById を複数回アクセスするのではなく、myElement にアクセスします。

that = this または self = this を設定すると、どこでも「that」または「self」にアクセスできるようになり、一部のオブジェクトの再ロードが防止されます。

于 2012-05-30T15:19:36.037 に答える