2017-09-04 6 views
3

私は次のコードを持っています。文字列変数が独立しているのに、なぜ3つのオブジェクトがすべて同じ配列を参照するのでしょうか?どのように明示的に追加することなく、それを修正することができる:関数Bを(){this.arr = [];}javascriptでプロトタイプを使用した継承

function A(){ 
 
    this.text = ""; 
 
    this.arr = []; 
 

 
    this.action = function(){ 
 
    this.text+="z"; 
 
    this.arr.push(1); 
 
    } 
 

 
    this.test = function(){ 
 
    console.log(this.text+"|"+this.arr); 
 
    } 
 
} 
 

 
function B(){ 
 
    
 
} 
 

 
B.prototype = new A();   
 
B.prototype.constructor = B; 
 
var B1 = new B(); 
 
var B2 = new B(); 
 
var B3 = new B(); 
 

 
B1.action(); 
 
B2.action(); 
 
B3.action(); 
 
B1.test(); //z|1,1,1 
 
B2.test(); //z|1,1,1 
 
B3.test(); //z|1,1,1

+0

親コンストラクタが行うことをすべて繰り返すのではなく、 'function B(){A.コール(this)}'を使うべきです。説明のために – Bergi

答えて

0

説明は次のようになります

プロトタイプがライブ鎖でありますオブジェクト間。 BのプロトタイプはAの単音インスタンスであるため、配列propは参照渡しされます。つまり、Bインスタンスごとに、プロトタイプ上の同じAインスタンスにアクセスできます。これは最初は混乱するかもしれませんが、それはJavaScriptのプロトタイプの魔法です。

これはプロトタイプの継承に関する警告です。プロトタイプ上のものはすべて、各インスタンスに渡されます。属性の異なるインスタンスを維持するために、コンストラクタ内のオブジェクトの属性を初期化します。

JSのオブジェクト(配列など)を扱うときは、参照渡しされます。 JSのプロトタイプシステムを利用するために

私はそうのようなものを示唆している:私たちは「親」からメソッドを再利用し、私たちの「子」でローカライズされた配列を持っている

function A(){ 
    this.text = ""; 

    this.action = function(){ 
    this.text+="z"; 
    this.arr.push(1); 
    } 

    this.test = function(){ 
    console.log(this.text+"|"+this.arr); 
    } 
} 

function B(){ 
    this.arr = []; 
} 

B.prototype = new A(); 

この道を。一見すると、これは古典的なOOPの継承のように見えるかもしれませんが、それは少し異なります。

あなたはJSでのプロトタイプについての詳細を読みたい場合は、私はこのことができます。このarticle

希望をお勧めします。

+0

感謝します。問題は、Aから継承したC、D、Eもあり、コードを複製したくないということです。私は代わりに寄生虫の継承を使用しなければならないと思う。 https://stackoverflow.com/a/2107586/5902472 – Ilya

+0

いいえ、このコードは使用しないでください。 [それはまだ間違っている](https://stackoverflow.com/a/17393153/1048572?Benefits-of-using-Object.create-for-inheritance) – Bergi

+0

@Bergiは参考にしていただきありがとうございます。前に仕事をしていない。プロトタイプの継承を達成する最善の方法ではないと私は同意する。 –

関連する問題