2009-09-03 100 views
12

我剛剛開始閱讀道格拉斯克羅克福德的「Javascript良好部分」,他在那裏解釋增強基本類型。Javascript增加基本類型(原型繼承)的疑問

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

這樣做之後的那一刻,addMethod可用像字符串所有的基本對象,等。這使我感到困惑

[1]爲什麼會出現這種情況當我還沒有添加到Object.prototype

[2]爲什麼添加方法Function.prototype的被反映在所有基本對象?

我很新的JavaScript和原型繼承。所以我不知道我的問題是否愚蠢?

+0

不,這是JavaScript的執行原型繼承是愚蠢的。其奇怪的使用函數作爲構造函數樣式給你沒有原型的潛在優勢,但仍然與大多數程序員所理解的基於類的繼承無異。很高興能夠準確理解JavaScript原型正在做什麼,但不要期望突然明白爲什麼該模型有意義。因爲它不。 – bobince 2009-09-03 15:16:44

回答

16

他大概的意思正是這樣做之後,addMethod成爲可用於所有基本 對象 對象類型像字符串,數字等,這是因爲String對象是一個函數(但字符串創建的對象都沒有)。

例如,鑑於

var s = ''; 

你可以做

String.addMethod(...); 

但不

s.addMethod(...); 

JavaScript的類型系統的簡要介紹到這裏:

JavaScript並不有正常的課程概念。相反,通過將任何函數轉換爲構造函數,可以通過在調用時將new關鍵字放在它前面來達到相同的效果。

E.g:給予

function MyFunction(x) { this.myX = x; } 

如果你調用它像

var myObj = new MyFunction(10); 

它會創建一個名爲MyObj中的對象。這個對象將有一個名爲myX的成員變量。該函數myFunction是考慮對象的構造函數(並存儲在「構造」特性

(獎金的問題:如果你調用該函數上面沒有新的關鍵字,即var x = MyFunction(10)會發生什麼,答案很可能驚奇任何明智的人)

現在您已經看到了如何將任意函數轉換爲構造函數。內建對象完全相同,字符串對象由函數String創建,數字由函數創建編號等

就像是由函數創建的那些內置的對象,每個對象的這些功能也是通過「功能」功能創建(亞克西!)。

現在到原型。

在上面的例子中

,如果你的地方寫

MyFunction.prototype.someNewMethod = function() {} 

由MyFunction的構造函數創建的所有對象/功能會出現有所謂someNewMethod一個額外的成員函數。你可以用原型做很多其他有趣的事情,比如替換原型,或者替換原型的原型,但我不是這方面的專家。

+0

根據'this.prototype [name]'判斷,我認爲你完全正確。 – 2009-09-03 11:29:48

+1

你能解釋一下嗎?找到困難的概念。 – 2009-09-03 12:14:14

+0

@erikkallen 如何是字符串對象類型(或任何其他基本對象類型)的函數?它是否像String對象有一個構造函數是一個Function對象?請多解釋一下! – sriramptr 2009-09-03 16:22:20

1

在面向對象的JavaScript,功能可以作爲一個類&構造函數。所以,如果你的類被命名爲MyObject,你可以做到以下幾點:

// create a class/constructor 
function MyObject() { 
    // ... 
} 

// add a static method to the MyObject class 
MyObject.someFunction = function() { 
    // ... 
} 

// add an instance method to the MyObject Class 
MyObject.prototype.someFunction = function() { 
    // ... 
} 

在您的例子中,addMethod加入作爲實例方法的功能類,這意味着它是提供給函數的所有實例。 MyObject函數/類/構造函數是Function的一個實例,因此您可以在其上調用addMethod。這適用於大多數任何對象類型,但不適用於IE和其他瀏覽器中的HTMLElements。

1
  1. JavaScript中的函數是對象。所有對象都有一個到Object.prototype的隱藏鏈接 。因此,對於第一個聲明:

    > `Function.prototype.addMethod=function(name,func) {} 
    

    您已經聲明鏈接到其自身連接到Object.prototype中Function.prototype的功能。

  2. 對於第二部分的只是一個任務,你要設置的名稱值對的Object.prototype中,將返回add方法的所有字符串,數字對象,因爲它是所有在原型聲明。