爲什麼當一個函數的定義是隱式設置其構造
這不是發生了什麼。你誤解了函數prototype
屬性的用途。
JavaScript中的任何函數都可以是構造函數。 「構造函數」僅僅是一個用new
調用的普通函數,例如new foo()
。
當函數調用new
時,函數返回一個新創建的對象,其原型鏈以函數的prototype
屬性開頭。對象的__proto__
屬性(或ECMAScript條款中的[[Prototype]]
內部屬性)設置爲構造函數的prototype
屬性。
function Boat() { }
var titanic = new Boat();
console.log(titanic.__proto__ == Boat.prototype); // true
由於函數可以被用作在任何時間與new
一個構造,每一個功能必須有一個prototype
屬性用於構造實例作爲其原型鏈的開始使用。
實例的constructor
屬性用於幫助該實例識別哪個構造函數創建它。爲了便於實現,該實例具有從其原型鏈繼承的constructor
屬性,該原型鏈設置爲以構造函數的prototype
屬性開始。任何時候創建一個函數對象時,都會提供一個prototype
屬性,並且該prototype
屬性的constructor
屬性設置爲該函數本身。
function Boat() { }
var titanic = new Boat();
// what constructor function made this instance? The Boat function did
console.log(titanic.constructor == Boat);
// does titanic have its own `constructor` property? no, it does not
console.log(titanic.hasOwnProperty("constructor") == false);
// the `constructor` property is inherited from the prototype chain
console.log(titanic.__proto__.constructor == Boat);
// titanic's prototype chain begins with `Boat.prototype`
console.log(titanic.__proto__ == Boat.prototype);
// these are the same
console.log(titanic.__proto__.constructor == Boat.prototype.constructor);
// these are also the same
console.log(titanic.constructor == Boat.prototype.constructor);
此行爲是在ES5 13.2, Creating Function Objects所描述的,步驟16到18:
- 創建一個新的本地的ECMAScript對象,讓˚F是對象。
- 如8.12所述,設置除[[Get]]之外的所有內部方法F。
- 設置F的[[Class]]內部屬性爲「
Function
」。
- 將[[Prototype]]內部屬性F設置爲15.3.3.1中指定的標準內置函數原型對象。
...
- 讓原是創建一個新對象如將被表達
new Object()
其中Object
是標準內置構造的結果具有該名稱的構造函數。
- 呼叫原與參數 「
constructor
」 的[[DefineOwnProperty]]內部方法,屬性描述符{[[價值]]:˚F,...} ...
- 調用[[DefineOwnProperty ]] f控制參數 「
prototype
」 的內部方法,屬性描述符{[[超值]:原,...} ...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor返回到創建實例的原型對象函數的引用。請注意,此屬性的值是對函數本身的***引用,而不是包含函數名稱的字符串。 – teynon