2015-05-05 38 views
-1

我發現,如果我有以下幾點:爲什麼使用functionName()== functionName.prototype.constructor()

var functionName = function(){console.log("this is a function!")} 

調用functionName相當於functionName.prototype.constructor因爲他們都持有上述函數定義。

我想我只是想解釋一下如何將函數用作JavaScript中的對象,以及如何與原型繼承相關。這是一個很寬泛的問題,所以大多要鑿掉它,我想知道爲什麼一個函數的定義被隱式地設置爲它的構造函數。我想這與支持new functionName()對象構建範例有關。

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor返回到創建實例的原型對象函數的引用。請注意,此屬性的值是對函數本身的***引用,而不是包含函數名稱的字符串。 – teynon

回答

1

爲什麼當一個函數的定義是隱式設置其構造

這不是發生了什麼。你誤解了函數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:

  1. 創建一個新的本地的ECMAScript對象,讓˚F是對象。
  2. 如8.12所述,設置除[[Get]]之外的所有內部方法F
  3. 設置F的[[Class]]內部屬性爲「Function」。
  4. 將[[Prototype]]內部屬性F設置爲15.3.3.1中指定的標準內置函數原型對象。

...

  • 是創建一個新對象如將被表達new Object()其中Object是標準內置構造的結果具有該名稱的構造函數。
  • 呼叫與參數 「constructor」 的[[DefineOwnProperty]]內部方法,屬性描述符{[[價值]]:˚F,...} ...
  • 調用[[DefineOwnProperty ]] f控制參數 「prototype」 的內部方法,屬性描述符{[[超值]:,...} ...
  • 0

    的JavaScript只有一個結構 - 它們是對象。每個對象都通過其原型鏈接到另一個對象。在調用函數屬性時,JavaScript會查找對象的原型,父對象的原型等,直到找到您正在查找的屬性。原型搜索中的最後一行類似於如果調用toString(),它將搜索此內容,除非重寫了toString()屬性,否則它將在Object.prototype中找到toString()。

    當您聲明一個函數時,解釋器會創建一個新的函數對象並填充原型屬性。注意:原型的默認值是一個帶有屬性構造函數的對象。

    function functionName() {} 
    var newFunction = new functionName(); 
    newFunction.hasOwnProperty('constructor') //false 
    newFunction.prototype.hasOwnProperty('constructor') //true as you noted above 
    
    相關問題