1

オブジェクトのメソッドを宣言するには、次の 2 つの方法があります。

最初の方法はself=thisイディオムを使用します。

function SelfIdiomExample(name){
    var self = this;

    self.sayHello = function (name){
         alert("Hello, "+name);
    }
}

これは、メソッド内のオブジェクトへの参照が必要な場合 (たとえば、メソッドがコールバックとして渡される場合) に役立ちます。もう 1 つの方法は、プロトタイプを変更することです。

function PrototypeModExample(){
   //pass
}

PrototypeModExample.prototype.sayHello = function(name){
   alert("Hello, "+name);
}

どちらも同じ結果になります。

var sieg = new SelfIdiomExample();
var pmeg = new PrototypeModExample();

sieg.sayHello("Barnaby");
pmeg.sayHello("Josephine");

self=thisイディオムの使用例は理解していますが、次のことを疑問に思っています。

コンストラクターで作成されたメソッドとプロトタイプで作成されたメソッドを使用すると、パフォーマンスが低下しますか?

4

2 に答える 2

2

さて、これはここにあります:

var self = this;

パフォーマンスへの影響はまったくありません。ローカル変数にアクセスするだけなので、非常に高速です。ネストされた関数からでも、これは JavaScript での非常に高速な操作です。

ただし、コンストラクターで作成されたメソッドとプロトタイプで作成されたメソッドには、パフォーマンスに大きな違いがあります。

この例では:

var PrototypeModExample = function(){
  this.name = "Joe";
};

PrototypeModExample.prototype.sayHello = function(){
   alert("Hello, " + this.name);
};

var a = new PrototypeModExample();
var b = new PrototypeModExample();
console.log(a.sayHello === b.sayHello); // true

コンストラクターのすべてのインスタンスは、同じ関数オブジェクトにアクセスできます。===これは、演算子を使用して 2 つのインスタンスの関数オブジェクトを比較することで証明できます。trueそれらが同じオブジェクトである場合にのみ返されます。したがって、グローバルには 2 つのインスタンスがありますが、sayHelloメソッドの実装のために 1 つの関数オブジェクトを共有しています。これは、新しいインスタンスを作成するときに、関数が既にセットアップされ、作成されていることを意味します。

つまり、すべてのインスタンスobj.sayHelloは、インスタンスが存在する前に作成された同じ関数オブジェクトを指します。


しかし、これは一方で:

function SelfIdiomExample(name){
    var self = this;
    this.name = "Joe";

    this.sayHello = function(){
         alert("Hello, " + self.name);
    }
}

var a = new SelfIdiomExample();
var b = new SelfIdiomExample();
console.log(a.sayHello === b.sayHello); // false

動作が異なります。===これで、比較が偽であることがわかります。これは、インスタンスごとに新しい関数オブジェクトが作成されたためです。この関数を作成するには、時間 (解析する必要があります) とメモリ (その関数のこの一意のバージョンを保存する必要があります) が必要です。したがって、これらのインスタンスを多数作成すると、この方法は遅くなり、より多くのメモリを消費します。

つまり、すべてのインスタンスobj.sayHelloは、インスタンス自体が作成されたときに作成された一意の関数オブジェクトを指します。


したがって、通常はプロトタイプ方式が好まれます。特に多数のインスタンスが存在する可能性がある場合は、各インスタンスがそのメソッドの関数オブジェクトを共有できるためです。

于 2012-08-21T00:06:06.677 に答える
1

いつものように、次のような質問に答えるためにテストする必要があります: http://jsperf.com/this-vs-self/2

テストすると、大きな違いはないように見えます (場合によっては、わずかに有利な数パーセント未満self)。の利点の 1 つselfは、変数名を 1 文字に変更することで最小化できることです。これが明らかに、一部のフレームワークで使用されている理由です。

あなたの例では、の使用selfは無関係であり、必要ではないと思います。通常、人々selfはクロージャーが使用されthis、一部のコールバックの値が、次のようにしたいものでなくなった場合にのみ使用します。

counter.prototype.incrementWithDelay(delay) {
    var self = this;
    setTimeout(function() {
        self.counter++;
    }, delay);
}

ただし、通常の方法しかない場合は、 を使用する理由はほとんどありませんself

counter.prototype.set(val) {
    this.counter = val;
}
于 2012-08-21T00:06:02.503 に答える