2016-12-05 15 views
2

一つのこと... コンストラクタ関数のprototypeプロパティを使用してメソッドを追加するのはなぜですか?私はプロトタイプとコンストラクタ関数を理解していない

が、私は「名前」プロパティと「logNameは」メソッドを持つオブジェクトが作成されます。このコンストラクタ関数を持っていると言う

function MyExample(param1){ 
    this.name = param1; 
}; 

MyExample.prototype.logName = function(){ 
    console.log(this.name); 
} 

私は、コンストラクタ関数の(myExample)プロトタイプにメソッド(logName)を追加したことを理解しています。このオブジェクトが 'name'プロパティと 'logName'メソッドを継承するこのコンストラクタ関数を使用して新しいオブジェクト(me) 。 logNameはメソッドは、新しいオブジェクトの(私の)プロト財産の一部となるだけでなく、コンストラクタ関数が作成されたオブジェクトにlogNameはメソッドを追加する理由

var me = new MyExample('bob'); 
me.logName(); //bob 

..But? (コンストラクタ関数のプロトタイプではありません)同じ結果を提供しませんか? 'logName'は新しいオブジェクトのprotoプロパティの一部ではありません。 2番目の例では

function MyExample(param1){ 
    this.name = param1; 
    this.logName = function(){ 
     console.log(this.name) 
    }; 
}; 

var me = new MyExample('bob'); 
me.logName(); //bob 

答えて

6

はあなたがMyExampleの新しいインスタンスを作成するたびlogName機能を再作成します。 MyExampleのプロトタイプを使用すると、logNameメソッドがMyExampleオブジェクトのすべてのインスタンスで共有され、コンテキストが自動的に渡されます。

プロトタイプを使用すると、後でそのタイプの既存のオブジェクトからアクセスできる新しいメソッドを追加することも、あるタイプのすべてのオブジェクトのメソッドをグローバルに変更することもできます。

あなたはより多くの情報をご希望の場合は、この質問は同じトピックに触れ、Advantages of using prototype, vs defining methods straight in the constructor?

1

コンストラクタでメソッドを作成すると、問題は、それがMyExampleのすべてのインスタンス間で共有されていないことです。

代わりに、それぞれMyExampleには、それ自身の機能のコピーがあります。インスタンスの数が増えるにつれ、より多くのメモリを占有し、何らかの理由ですべてMyExampleを実行時に変更する場合は、プロトタイプを変更する代わりにすべてのインスタンス関数を変更する必要があります。

ウィキペディアと同じ「コピー」を見ている人と、ウィキペディアのすべてをハードディスクに保存して読んでいる人の違いは、すべてです。それは無意識のうちに余分なハードドライブの空き領域を使い果たし、Wikipediaが更新されると、新しいバージョンをダウンロードするまで誰もが間違っています。

何らかの理由でインスタンス間で非常に似ているが、各インスタンスごとに(たとえばクロージャ変数を使用して)わずかに異なる関数が必要な場合は、コンストラクタでメソッドを作成するのが適切な方法かもしれません。

0

プロトタイプにメソッドを追加すると、コードの抽象度が向上します。

たとえば、メソッドがインスタンスに関連付けられていないため、十分に互換性のある非インスタンスでメソッドを呼び出すことができます。このよう:番目の内部メソッドを定義し、さらに

[].slice.call({0:'a', 1:'b', length:2}); // ["a", "b"] 

:あなたが唯一のインスタンス上で、あなたのメソッドを定義した場合

Array.prototype.slice.call({0:'a', 1:'b', length:2}); // ["a", "b"] 

、方法を借りるために無用のインスタンスを作成する必要がありますコンストラクタは、各インスタンスが異なるコピーを受け取ることを意味します。

new MyExample('bob').logName === new MyExample('bob').logName // false 

これは、より多くのメモリを浪費することを意味します。

関連する問題