2014-01-24 129 views
9

剛讀完「JavaScript:The Good Parts」 - 這本好書。但我對第33-34頁的一個非常重要的話題感到困惑 - 增加類型。它描述了添加到Function.prototype的新方法的創建,所以當使用新方法調用時,所有函數都可以使用該方法。很公平。但後續的例子顯示了在Numbers和Strings中使用這種方法。我在想,它是對象 - 不是功能。我在這裏錯過了什麼?JavaScript - 好的部件:函數原型vs對象原型

Function.prototype.method = function (name, func) { 
    this.prototype[name] = func; 
    return this; 
}; 

用例:

Number.method('integer', function() { 
    return Math[this < 0 ? 'ceiling' : 'floor'](this); 
}); 

document.writeln((-10/3).integer()); //-3 
+6

功能是對象。 –

+1

@MattBall我不認爲這是OP的要求。相反,我想他/她在問'Number'是如何從'Function'派生的。 – mc10

+0

是的,正好@ mc10。 – svenyonson

回答

8

您的方法添加到Number原型,所以每數實例訪問它。換句話說,因爲在Number原型中有一個名爲「integer」的屬性,所以任何從任何Number實例訪問該屬性的嘗試都會成功。這就是將屬性放在構造函數原型上的全部內容。

當在.運算符的左側出現JavaScript基本編號時,語言會自動將其放在Number實例中,以便方法調用有意義。我們來看看這個「方法」函數是如何工作的。在通話中

Number.method("integer", function() { ... }) 

發生了什麼事?那麼,在「方法」函數中,「名稱」參數是「整數」。然後函數參數被指定爲this.prototype的屬性。調用「方法」函數的this是什麼?這是數字構造函數。因此,函數原型上的「方法」函數—因此可用於所有函數實例,如Number構造函數(例如—)將給定函數作爲所涉及的構造函數原型的屬性添加。

爲什麼「方法」屬性作爲數字構造函數的屬性可見?因爲Number構造函數本身就是一個函數。 「方法」函數是作爲函數原型的一個屬性創建的,所以這意味着它對包括數字構造函數的每個函數實例—都可見。

+0

是的,但當'方法'被添加到Function.prototype時,它如何被添加到數字原型?我可以理解'方法'是否被添加到Object.prototype。 – svenyonson

+1

@svenyonson'Number'是一個函數。在你的瀏覽器控制檯中試試這個:Numberof Number' –

+0

@svenyonson就像Matt Ball說的那樣,Number構造函數本身就是一個函數實例。 – Pointy

8

功能對象VS功能實例對象

首先,在JavaScript中,一個函數也是對象。從這裏,我的意思不是new()構造創建的對象,而是函數本身。爲避免混淆,我會參考函數對象以及使用函數的new()構造創建的對象函數實例對象

_ _原和原型屬性

不限函數對象在javascript具有兩個屬性:_ _原和原型。此外,任何函數實例對象(使用新構造函數創建)具有屬性_ proto __ proto _是什麼定義了繼承。這方面的一些很好的資源,可以在

http://zeekat.nl/articles/constructors-considered-mildly-confusing.html

找到如何定義繼承?

一個目的objA繼承另一個目的objC如果objA和objC通過任何數量的_ _原的連接。所以如果objA有_ proto _等於objB,並且objB有_ proto _等於objC,則objA繼承objB和objC,而objB繼承objC。

繼承是什麼意思?

這意味着任何繼承對象可以使用繼承對象的任何屬性。

什麼是Function.prototype的

這是誰_原_每函數對象所引用的對象。這意味着每個函數對象都有權訪問Function.prototype的屬性,因爲每個函數對象都繼承了Function.prototype對象。這也意味着如果方法屬性被添加到Function.prototype對象中,它將可用於所有可能的函數對象在javascript中。這包括字符串,數字等。

this.prototype [name] = func;

這是指 Function對象當「方法」是從功能對象中調用就像數字,字符串,等等。這意味着我們現在在 Function對象與名稱的新特性「名稱」,它的一個函數'func'。

原型財產函數對象有什麼好處

一個函數對象原型功能實例對象提到的_使用該函數的新構造創建的原始_

如果以下被執行:

Number.method( '整數',函數(){...});

然後Number.prototype有整數在其中定義的方法。這意味着每個號碼功能實例對象,例如,新Number(2.4)將從Number.prototype繼承此新屬性'integer',因爲該號碼函數實例對象將其_ proto _設置爲Number.prototype。

0

NumberObject或其他內建類也是構造函數,則構造函數是JavaScript中的函數。有在ECMAScript規範絲束重要描述:

每個內置函數和每個內置構造所具有的功能的原型對象,其是表達Function.prototype的(15.3.4)的初始值,作爲它的[[Prototype]]內部屬性的值。

除非另有規定,否則每個內置原型對象都有Object prototype原型對象,它是表達式Object.prototype(15.2.4)的初始值,作爲其[[Prototype]]內部屬性的值,除Object原型對象本身。

所以在控制檯中,我們可以執行的代碼:

Number.prototype.__proto__.isPrototypeOf(Function)

結果是true

這樣Number可以訪問Function.prototype的方法是否合理。

與此同時,如果我們將Object.prototype擴展爲Object.prototype.say = 'hello';,我們也可以訪問say的屬性Function.say

因爲Function.prototype.isPrototype(Object)true