web-dev-qa-db-ja.com

プロトタイプの目的は何ですか?

可能性のある複製:
JavaScriptでのプロトタイプ継承の理解

それでは、JSのOOPの考え方はやや新しいものです。

これらの2つのコードスニペットの違いは次のとおりです。

function animal(){
    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
    }
}
function animal(){
    this.name = 'rover';
}
animal.prototype.set_name = function(name){
    this.name = name;
}

どちらも同じことをしているので、違いは何ですか?

220
Quinton Pike

プロトタイプを使用すると、新しいオブジェクトが作成されるたびにその関数を再作成する必要がないため、オブジェクトの作成が高速になります。

これを行うとき:

function animal(){
    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
    }
}

set_name関数が作成されますde novo動物を作成するたびに。しかし、あなたがこれをするとき

animal.prototype.set_name = function(name){
    this.name = name;
}

関数を毎回再作成する必要はありません。プロトタイプ内の1つの場所に存在します。したがって、someAnimal.set_name("Ubu");を呼び出すと、thisコンテキストがsomeAnimalに設定され、(唯一の)set_name関数が呼び出されます。


ただし、最初の構文を使用することには1つの利点があります。この方法で作成された関数は、プライベートデータにアクセスできます。

function animal(){
    var privateData = 'foo'

    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
         alert(privateData); //will alert 'foo'
    }
}

ダグラス・クロックフォードは、このような「特権のある」ように作成された関数を呼び出します。それらは、パブリックデータとプライベートデータの両方にアクセスできます。

312
Adam Rackis

これらの関数から新しいオブジェクトを作成すると、違いが現れます

var animal1 = new animal();

最初の関数によって作成されたすべてのオブジェクトには、異なるnameおよびset_nameプロパティがあります。ただし、2番目の関数によって作成されたすべてのオブジェクトは、set_nameプロパティを共有します。

33
user366161

最初の例では、それぞれの動物にset_name関数の独自のプロパティがありますが、2番目の例では、プロトタイプを介して同じ関数を共有しています。

最初のバージョンの利点は、メソッドがコンストラクター内で宣言されたローカル(プライベート)変数にアクセスできることです。

2番目の方法の利点は、必要なメモリが少なく(メソッドを100万回ではなく1回だけ保存するため)、現在のJSエンジンでよりパフォーマンスが高いことです。

2番目のメソッドを使用して、すでに作成されたインスタンスにも影響を与える方法で、クラスのメソッドを変更または追加することもできます。

22
hugomg