2011-06-29 44 views
6

我有這個問題... B是基類,A是派生類...雖然A是從B派生而來的,但A的各種對象指向相同的對象B.使用JavaScript對象原型擴展類的問題

的我知道我有分配B的對象A的原型,使B.

的孩子

,但一個不同的對象,他們應該有不同的地址空間來保存變量,右?你能糾正這個嗎?

function B(){ 

     this.obj = {}; 
    } 

    function A(){ 

    } 

    A.prototype = new B(); 

    var a = new A(); 
    var b = new A(); 
    var c = new A(); 

    console.log(a.obj == b.obj); //prints true 
    console.log(a.obj === b.obj); //prints true 

    a.obj.name = "stackoverflow"; 
    console.log(b.obj.name); //prints stackoverflow 

我應該在這段代碼中做些什麼改變,以便給出下面的結果。

a.obj === b.obj //must be false 

a instanceof A; //must be true 
a instanceof B; //must be true 
+1

你到底在問什麼?您發佈的代碼存在哪些問題或預期行爲存在差異? – Slavo

+0

請看看,我已更正了這個問題... –

回答

4

這就是爲什麼你不應該在原型上具有可變值(特別是對象或數組)的原因 - 相同的值將在所有對象實例之間共享,並且可以在任何對象實例中進行更改。在這裏,你能避免使用Object.create問題創建原型時,不會調用B構造函數:然後

構造 A
A.prototype = Object.create(B.prototype); 

應該調用B構造爲每個新的對象:

function A() { 
    B.call(this); 
} 

對於不支持Object.create()的瀏覽器,您可以像http://javascript.crockford.com/prototypal.html中提到的那樣模擬它。

1

這是Javascript中原型的一部分,我建議您閱讀this excellent thread

+0

感謝您的建議... –

2

值是通過引用來分配的,並且由於A的所有實例都使用與它們的原型相同的B實例,它們都引用相同的'B'。

所以這正是這裏所期望的。解決這個問題的一種方法是添加(例如)一個'初始化'方法的B'類',然後你可以在A構造函數中調用它。

您也可以不是使用'new B()'來定義原型,並使用Object.create來代替。的Object.create不調用B的構造函數,但你可以從A

function A() { 
    B.call(this); 
} 
+0

我試過這個,我的第二個要求在這裏不起作用...也就是, 一個B的實例==真 –

+0

謝謝它的工作... –

0

調用父類的構造函數如果你想有一個實例有一個本地物業obj的屬性添加到A,不B

function B(){ 
} 

function A(){ 
    this.obj = {}; // <<< this.obj here 
} 

A.prototype = new B(); 

var a = new A(); 
var b = new A(); 
var c = new A(); 

console.log(a.obj == b.obj); //=> prints false 
console.log(a.obj === b.obj); //=> prints false 

a.obj.name = "stackoverflow"; 
console.log(b.obj.name); //=> undefined 

另一種方式擁有當地obj屬性的A實例是B的原型使用setter方法:

function B(){ 
    B.prototype.setObj = function(obj){ 
    this.obj = obj; 
    return this; 
    } 
} 
//... 
a.setObj({}).name = "stackoverflow"; 
console.log(a.obj.name); //=>prints stackoverflow 
console.log(b.obj.name); //=>undefined 
+0

正如我所說,obj是B的屬性,需要從派生類A訪問。你的意思是,我應該從B複製所有的屬性到A? –

+0

如果從'A'中的'B'派生'obj','obj'等於'A'的所有實例(它的原型是'B')。這就是它的工作原理。然而,你可以在B的原型中聲明一個方法,設置'this.obj'。查看我的編輯。 – KooiInc

+0

感謝您的建議... –