2012-04-27 206 views
5

請幫我理解這段代碼。Javascript對象繼承

var person = { 
    'first-name': 'FirstName', 
    'last-name': 'LastName', 
    'gender': 'Male' 
}; 

var anotherPerson = new Object(person); 
anotherPerson.desig = 'Designation'; 

console.log('Another person designation: ' + anotherPerson['desig'] + ', person designation: ' + person['desig']); 

我預計輸出爲Another person designation: Designation, person designation: undefined,但讓我吃驚,我發現它是`Another person designation: Designation, person designation: Designation

據我anotherPerson正在擴大person對象和屬性設置爲anotherPerson應該是不可見的person對象。我錯了嗎?或者是這兩個對象都指向相同的位置?

[編輯]

現在甚至有更多的驚喜。

我將以下代碼添加到上面。

person.place = 'XYZ'; 
console.log(person['place'] + ', ' + anotherPerson['place']); // Expected: XYZ, undefined. Result: XYZ, XYZ. 

基於上述結果和答案,我認爲這兩個對象都指的是相同的位置。現在我又增加了幾行

person = undefined; 
console.log(anotherPerson['place']) //Expected: error, Result: XYZ. ??!?!? 
console.log(person['place']) // Expected: error, Result: error. 

有人可以告訴我一些明白這一點嗎? 感謝您的幫助提前

+0

這裏沒有繼承。只有兩個引用同一個對象。 – Cameron 2012-04-27 19:59:51

+0

那你怎麼克隆這個對象並製作一個新對象呢?我和OP一樣,可能會認爲新建立了一個NEW對象。 – DanRedux 2012-04-27 20:01:36

+0

請參閱:http://stackoverflow.com/questions/728360/copying-an-object-in-javascript – 2012-04-27 20:03:47

回答

2

你並沒有進行擴展或任何類型的繼承。

這更接近:

var Person = function() { 
    this["first-name"] = 'FirstName', 
    this["last-name"] = 'LastName', 
    this["gender"] = 'Male' 
}; 

var person = new Person(); 
var anotherPerson = new Person(); 

現在你有Person 2個單獨實例。如果你也想anotherPerson是一個子類..

var Person = function() { 
    this["first-name"] = 'FirstName', 
    this["last-name"] = 'LastName', 
    this["gender"] = 'Male' 
}; 

var AnotherPerson = function() { 
    this.desig = "Designation"; 
} 
AnotherPerson.prototype = new Person(); // inherit from Person 
AnotherPerson.prototype.constructor = AnotherPerson; // reset constructor 

var person = new Person(); 
var anotherPerson = new AnotherPerson(); 

console.log(person.desig); // undefined 
console.log(anotherPerson.desig); // Designation 
+1

我剛寫完第一段代碼; +1 – bhamlin 2012-04-27 20:05:26

+0

@Frits感謝您的回覆。我得到你已經解釋的代碼。所以當我們做'新的對象(人)'時,'anotherPerson'指的是同一個位置?我嘗試給'person'添加一個新屬性,'anotherPerson'能夠成功讀取新屬性。爲什麼這樣? – Anji 2012-04-27 20:08:07

+0

我不完全確定'新對象(人)'是做什麼的。也許它只是解決了'人'?我知道它不會從'person'神奇地延伸:P – Halcyon 2012-04-27 20:09:19

0

不是一個真正的解決方案,但對我來說,這就是我這樣,我可以擴展它克隆對象:

var anotherPerson = new Object(); 
for(i in person) anotherPerson[i]=person[i]; 

而不是

var anotherPerson = new Object(person); 

然後它按預期工作。

+0

我可以知道當我們執行'var anotherPerson = new Object(person)'時會發生什麼嗎? – Anji 2012-04-27 20:05:08

0

Object功能(注:同樣的,更令人吃驚的,如果你不熟悉,這是怎麼回事,適用於呼叫new Object(...))不會創建一個新的對象,如果它傳遞了非布爾,數字或字符串類型的東西;它只是返回已經存在的對象。 (理由:因爲它已經是一個對象,幾乎一切都在Javascript對象。)

因此,anotherPerson是完全相同的對象爲person,所以當你修改它,你修改person了。

我不認爲這是明智的行爲;但它是語言規範定義的。

0

如果你想擴展/繼承一個對象,那麼你可以做

var person = { 
    'first-name': 'FirstName', 
    'last-name': 'LastName', 
    'gender': 'Male' 
}; 
if (typeof Object.create !== 'function') 
{ 
    Object.create=function(o) 
    { 
     function F(){} 
     F.prototype=o; 
     return new F(); 
    } 
} 
var newPerson=Object.create(person); 
newPerson.age=25; 
newPerson.gender="Female"; 

console.log(person.gender); // Male 
console.log(newPerson.gender); // Female 

console.log(person.age); // undefined 
console.log(newPerson.age); // 25 

Fiddle

參考:Prototypal Inheritance in JavaScript

+0

道格拉斯克羅克福德的方式!完善。對, – Anji 2012-04-27 20:37:31

+0

是的,沒錯。 – 2012-04-27 20:38:28

0

在JavaScript

繼承實現一個通用的解決方案
function inherits(base, extension) 
{ 
    for (var property in base) 
    { 
     try 
     { 
     extension[property] = base[property]; 
     } 
     catch(warning){} 
    } 
} 
+0

爲什麼在try/catch? – alex 2015-12-15 20:05:06