3

重複の可能性:
Javascript-この対。プロトタイププロトタイプ
を使用することの利点と、コンストラクターでメソッドを直接定義することの利点は?
プロトタイプまたはインライン、違いは何ですか?

JavaScriptでクラスを作成する場合、これを使用してオブジェクト内でメソッドを宣言するのと、プロトタイプにアクセスして宣言するのはどうですか?同じ目的を果たしているように私には思えます。

window.onload = function() { 
    tc = new TestClass();
    tc.init(); //logs initting
    tc.reset(); //logs resetting
    tc.doSomething(); //logs doing something
};


var TestClass = function(){

    this.init = function(){
        console.log("initting");
    }

    this.reset = function(){
        console.log("resetting");
    }

    this.destroy = function(){
        console.log("destroying");
    }

}

TestClass.prototype.doSomething = function(){

    console.log("doing something");
}
4

3 に答える 3

3

ほとんどの場合、同じ機能結果が得られます。thisただし、内部的には、関数をにアタッチすると、型のすべてのインスタンスが関数の独自のコピーを取得するという点でまったく異なります。関数をにアタッチすることによりprototype、すべてのインスタンスが同じ関数インスタンスを共有します。プロトタイプを使用すると、メモリ使用量が削減されます。

于 2012-08-03T20:36:35.170 に答える
2

あなたが読む前に:英語は私の母国語ではありません;)

実際には、これプロトタイプはほとんど同じですが、これプロトタイプはjavascriptで明確な意味を持っています。

1)Javascriptは、プロトタイプの継承に基づいています。これは、あるオブジェクトが別のオブジェクトからプロトタイプモデルを継承できることを意味します。プロトタイプを使用すると、javacriptの継承を(制限付きで)エミュレートできます。次に例を示します。

// create a 'class' Vehicle
var Vehicle = function() {};
Vehicle.prototype.wheels = 0;
Vehicle.prototype.maxSpeed = 0;
Vehicle.prototype.displayInfo = function() { 
     alert("hello, I have " + this.wheels + " wheels and max speed of " + this.maxSpeed);
};

var vehicleInstance = new Vehicle();
vehicleInstance.displayInfo(); // displays: Hello, I have 0 wheels and max speed of 0

// create a 'class' Car using the prototype from Vehicle 
// and change some properties.
var Car = function(maxSpeed) { 
    if(maxSpeed)
      this.maxSpeed = maxSpeed;
};
// inherit the prototype from vehicle
Car.prototype = new Vehicle();  
// change some properties
Car.prototype.maxSpeed = 200;
Car.prototype.wheels = 4;

var car = new Car();
car.displayInfo(); // displays: Hello, I have 4 wheels and max speed of 200

2)このプロパティは、プロトタイプのプロパティよりも優先されます。次に例を示します。

var car = new Car(); // car prototype: maxSpeed = 200;
car.displayInfo() // displays: Hello, I have 4 wheels and max speed of 200

//set maxSpeed to 300 on 'this'
var car = new Car(300); // see Car definition above

// call displayInfo() in car instance. The Car 'class' doesn't have displayInfo()
// itself, but its prototype has. The javascript VM will look
// for displayInfo() in the car instance, if it not found in the
// instance it will look in car.prototype and on car.prototype.prototype etc.
// until it founds a property called displayInfo() 
// or reaches the end of the chain (Object.prototype).
car.displayInfo() // displays: Hello, I have 4 wheels and max speed of 300

これは、たとえば、プロトタイプのプロトタイプにも当てはまります。

var Class1 = function() { };
Class1.prototype.someValue = 1;

var Class2 = function() { };
Class2.prototype = new Class1();
Class2.prototype.someValue = 2; // this overrides the Class1.prototype.someValue prototype

var class2 = new Class2();
class2.someValue = 3; // this overrides the Class2.prototype.someValue;

3)プロトタイプで定義されたプロパティは、同じオブジェクトの新しいインスタンスごとにインスタンス化されるわけではありません。次に例を示します。

// create a new class and inherit the prototype model from Vehicle.
var Motorcycle = function() { };
Motorcycle.prototype = new Vehicle();
// motorcycles has 2 wheels
Motorcycle.prototype.wheels = 2;

var motorcycle = new Motorcycle();
motorcycle.dysplayInfo(); // displays: Hello, I have 2 wheels and max speed of 200

//now, if I change the method dysplayInfo from Vehicle, it will change for every
//object that inherits Vehicle prototype:
Vehicle.prototype.displayInfo = function() { 
    Alert("Wheels: " + this.wheels + ", Max speed: " + this.maxSpeed);
}

//observe that I didn't create another Motorcycle instance ,
//I'm using the same instance that I've created before change
//the Vehicle.dysplayInfo() method
motorcycle.displayInfo() // displays: Wheels: 2, Max speed: 200

ご覧のとおり、Vehicleで使用されているのと同じメソッドが、プロトタイプを継承するすべてのオブジェクトで使用されています。これにより、複数のオブジェクトに同じ関数を使用するため、コードがはるかに効率的になります。ファットプロトタイプから継承する何千ものオブジェクトを使用しても、メモリフットプリントを低く抑えることができます。

つまり、プロトタイプを使用することで、より効率的に実行され、より少ないメモリを使用する、明確に定義された継承ツリー(プロトタイプチェーンと呼びます)を使用して、オブジェクトのような強力な「クラス」を作成できます。

私がここで言ったことは、プロトタイプの継承/チェーンの主題を網羅していません。読むことができる他のリソースは次のとおりです。javascriptのプロトタイプを理解することは、優れた保守可能なコードを書くために不可欠なので、私はお勧めします。

ここで私が言ったことは、プロトタイプの主題を網羅していません: https ://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript?redirectlocale=en-US&redirectslug=Introduction_to_Object-Oriented_JavaScript

http://javascript.crockford.com/prototypal.html

http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/

于 2012-08-03T21:26:03.517 に答える
1

その特定のケースでは同じ効果がありますが、非常に異なります。1つの(?)主な違いは、を使用してアタッチされたメソッドthisは、オブジェクト自体のプロパティであり、プロトタイプのプロパティではないため、次のようにオブジェクトを反復処理することです。

for(var x in tc) {
    if(tc.hasOwnProperty(x)) {
        console.log('Has property ' + x);
    }
}

を使用して追加されたメソッドは省略されprototypeます。もう1つの違いは参照です。メソッドを割り当てると、this毎回新しい関数オブジェクトが作成されますが、プロトタイプを使用すると、それらはすべて同じ関数になります。(これはあなたが望むものであるかもしれないし、そうでないかもしれません、そしてそれはメソッドに追加のプロパティを添付するときに最も重要です。)

于 2012-08-03T20:37:21.823 に答える