2011-06-13 83 views
6

我試圖創建一個主對象,我可以創建多個實例,每個實例都繼承兒童(具有唯一/隔離屬性)。但是,當我這樣做時,對象的屬性(更改後)正在改變所有創建的對象。我可能沒有正確解釋,但這個例子應該很清楚。OOP Javascript - 在類中隔離對象

Main = function(){}; 

// Extending the main class with new object. Doing it this way so I can have these in 
// separate files. 
Main.prototype.foo = { 
    bar: 1 
} 

// First instance of Main(). 
var A = new Main(); 

// Second instance of Main(). 
var B = new Main(); 

// Set the bar property to different values for each Main() object. 
A.foo.bar = 2; 
B.foo.bar = 3; 

// Both A.foo.bar and B.foo.bar return 3. 
alert(A.foo.bar); 
alert(B.foo.bar); 

我試圖去有發生,是A.foo.bar返回2 B.foo.bar返回3,所以,我已經分離出相互獨立的對象。

任何想法?我是否錯過了一些顯而易見的東西?將不勝感激!

+1

爲什麼你有兩次設置「foo」?這只是一個抄寫錯誤? – Pointy 2011-06-13 01:31:21

回答

5

「foo」屬性位於原型對象上,並且只有其中一個。當您通過任何實例設置它時,您都會影響相同的共享屬性。

您可以在構造函數中添加實例屬性:

function Main() { 
    this.instanceProperty = 1; 
    } 

那麼這將是每個實例。

原型不是「主模板」或類似的東西;這是一個真正的對象。它不會複製到實例上。相反,運行時知道它在那裏,並且在實例上實際上並不存在的實例上引用屬性時,它知道要走向原型鏈並在那裏尋找屬性。

1

由於您正在編輯原型上的東西,它會影響每個對象。

但是,你可以這樣做:

A.x = 2; 
B.x = 3; 

然後你就會有不同的結果。

或者,你可以有這樣的事情:

Main = function(val){ 
    this.x = val; 
} 

A = new Main(2); 
B = new Main(3); 
3

其他的答案都或多或少正確的,但他們錯過的是,有

Main.prototype.foo = { 
    bar: 1 
}; 

之間的差異
Main.prototype.bar = 1; 

在這兩種情況下,實例化一個新的Main將創建一個新的在其原型鏈中有一個屬性foobar。在這兩種情況下,實例級屬性可以在不影響其它實例被重新定義:

function Main() {}; 
Main.prototype.foo = { 
    bar: 1 
}; 
Main.prototype.bar = 1; 

a = new Main(); 
b = new Main(); 

a.foo = { bar: 2 }; 
console.log(a.foo.bar, b.foo.bar); // 2 1 

a.bar = 2; 
console.log(a.bar, b.bar); // 2 1 

但是當你實例化一個新Main,實例變量foo參考單個對象,{bar:1},這是在所有實例中共享。因此,當您設置a.foo.bar時,您正在更改通用對象,而不是實例變量;實例變量是參考a.foo

您不必在構造函數中初始化實例屬性。標準方法是直接在原型上設置bar,即Main.prototype.bar = 1,這會給你獨立的實例變量,初始化爲1。但是,如果您需要更復雜的數據結構(對象,數組或其他類的實例),則無法將其創建爲原型上的屬性,因爲您將給每個實例提供一個公共對象的引用 - 所以在構造函數中是要走的路:

function Main() { 
    // instance-level object 
    this.foo = { 
     bar: 1 
    }; 
} 
+3

看到這個優秀的帖子,以清楚地瞭解原型是如何工作的:https://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/ – rahulmohan 2011-06-13 05:28:53

+0

我認爲這個陳述「實例變量foo是對單個對象的引用「對於理解在foo中操作屬性的行爲很重要。 – maulik13 2012-10-21 20:44:56