2012-09-30 125 views
0

爲了理解JavaScript構造函數,我一直在尋找this question帶參數的Javascript構造函數

在我看來,我理解它是合理的,但具有諷刺意味的是,當我試圖運行類似的代碼時,它根本不適用於我。

這是我的代碼

function Car(name) { 
    this.Name = name; 
    this.Year = 1999; 
} 

Car.prototype.Drive = function() { 
    document.write("My name is '" + this.Name + "' and my year is '" + this.Year + "'. <br />"); 
}; 

SuperCar = function() { }; 
SuperCar.prototype = new Car(); 

function SuperCar(name) { 
    Car.call(this, name); 
} 

var MyCar = new Car("mycar"); 
var MySuperCar = new SuperCar("my super car"); 

MyCar.Drive(); 
MySuperCar.Drive(); 

首先,這條線

SuperCar = function() { }; 

是必要的它運行在所有。如果我放棄它,我會在這一行發現錯誤「SuperCar未定義」。

SuperCar.prototype = new Car(); 

我不明白爲什麼要將SuperCar聲明爲空函數是必要的。

其次,當我運行代碼,我得到這樣的結果

My name is 'mycar' and my year is '1999'. 
My name is 'undefined' and my year is '1999'. 

顯然,對於MySuperCar,超級跑車(名稱)函數永遠不會被調用,但汽車()是。

添加此行不幫助

SuperCar.prototype.constructor = SuperCar; 

無論這是否

SuperCar.prototype.constructor = function(name) { 
    Car.call(this, name); 
}; 

(我一直在運行一個腳本標籤內的代碼在IE 9和Chrome 22)

我應該如何正確定義一個採用名稱參數的SuperCar構造函數?或者換一種說法,我怎麼能讓新款超級跑車(「我的超級跑車」)的召喚行爲按照我的預期行事(將名字命名爲「我的超級跑車」)?

+0

小提琴:http://jsfiddle.net/userdude/Gs4qu/你可能遠離'document.write',我會建議'document.body.innerHTML =「等等等等等等等等等等等等等等等等或DOM方法。 –

+1

它也工作,如果我註釋掉你問的函數變量:http://jsfiddle.net/userdude/Gs4qu/1/右下方,你有'功能SuperCar(名稱){...}宣佈和提升將它放在範圍的頂部。所以除非一段時間內這個函數不存在,或者最初是一個變量函數或函數變量(誰能說出不同之處?),我不明白爲什麼這會是一個問題。我也在這裏談論Chrome。 –

回答

4

你真的不應該創建Car爲原型的實例,但是隻創建一個從Car.prototype繼承的對象。詳情請參閱What is the reason to use the 'new' keyword at Derived.prototype = new Base。相反,使用

SuperCar.prototype = Object.create(Car.prototype); 

你的問題是,你的SuperCar S被空函數創建的 - 它返回一個對象沒有任何屬性。然而,它們繼承自new Car(),其nameundefined。這是發生在你的提琴,因爲函數聲明(與function關鍵字開始,退房this explanation)懸掛(提供無處不在的範圍內),並覆蓋由線

SuperCar = function() { }; 

讓您SuperCar構造函數不再次調用Car構造函數。 Fixed fiddle

2

您不需要空白功能。您創建了一個空的SuperCar函數,然後設置其原型,但隨後用新的定義SuperCar進行了重寫。

function SuperCar() {} 
SuperCar.prototype = new Car(); 

function SuperCar() {} // original SuperCar overwritten 
+0

不,您不需要將'constructor'屬性設置爲新實例。 – Bergi

+0

不,第二個函數聲明也不會覆蓋第一個函數聲明。 – Bergi

+0

@Bergi但它確實是那個空功能,因爲當我把它拿出來時它工作正常。 – 0x499602D2