在 JavaScript 中,每個函數對象都有一個預設的屬性 prototype,稱為函數對象的原型成員,這個屬性指向一個對象,稱為函數的原型對象,當我們每定義了一個函數的時候,JavaScript 就創建了一個對應的原型對象,也就是說,當我們定義一個函數的時候,實際上得到了兩個對象,一個函數對象,
在 JavaScript 中,每個函數對象都有一個預設的屬性 prototype,稱為函數對象的原型成員,這個屬性指向一個對象,稱為函數的原型對象,當我們每定義了一個函數的時候,JavaScript 就創建了一個對應的原型對象,也就是說,當我們定義一個函數的時候,實際上得到了兩個對象,一個函數對象,一個原型對象。原型對象是一個特殊的對象,函數的 prototype 成員指向它的原型對象。
可以通過函數對象的 prototype 成員取得這個原型對象的引用。
下麵定義一個函數對象 Person,然後通過 prototype 來取得它的原型對象。然後在它的原型對象上定義了一個方法。
05 |
Person.prototype.showPerson = function () |
07 |
alert( "Person Object." ); |
10 |
var alice = new Person(); |
這個原型對象上定義的成員將用來共用給所有通過這個函數創建的對象使用。相當於 C# 中的實例方法,對象,函數和原型在記憶體中的關係如下圖所示:
每個對象也都有一個原型成員 prototype,通過 new 函數創建的對象會通過函數的 prototype 找到函數的原型,然後將自己的原型指向這個對象。對於不是通過函數創建的對象實例和原型對象,它們的原型會被設置為 Object 函數的原型對象。
Object 函數對象是 JavaScript 中定義的頂級函數對象,在 JavaScript 中所有的對象都直接或者間接地使用 Object 對象的原型。 當訪問對象的屬性或者方法的時候,如果對象本身沒有這個屬性或者方法,那麼,JavaScript 會檢查對象的 prototype 對象是否擁有這個屬性或者方法,如果有,則作為對象的屬性或者方法返回,如果沒有,那麼將通過原型對象的 prototype 繼續進行檢查,直到原型對象為 Object 函數的原型對象為止。
但是 prototype 是一個特殊的屬性,在大多數的瀏覽器上,例如 IE 瀏覽器,都不能直接訪問對象的 prototype 成員。返回的結果為 undefined。不能賦予對象一個新的原型,只能通過創建它的函數來確定對象的原型。
函數對象的原型有一個特殊的用途,就是通過函數 new 創建出來的對象,會自動將函數對象的原型賦予新創建出的對象的原型。這樣,如果為某個函數設置了原型對象,那麼,所有通過這個函數創建的對象將擁有同樣的原型對象。通過這個方法,可以使這些對象共用相同的屬性或者方法,來模擬類型的概念。
在 jQuery 中,我們經常使用的 $() 函數就是定義在 window 對象上的 $() 函數。
1 |
jQuery = window.jQuery = window.$ = function ( selector, context ) |
4 |
return new jQuery.fn.init( selector, context ); |
這個函數實際上通過 new jQuery.fn.init( selector, context )來完成,也就是通過 init 函數創建了一個對象。
下麵重新指定了函數 init 的原型對象。所以 init 函數的原型對象就是 fn 對象。
2 |
jQuery.fn.init.prototype = jQuery.fn; |
這樣所有通過 $ 創建出來的對象都將共用 fn 對象上的成員。因此,jQuery 對象都有了類似 attr 、html 等等方法了。
整理了一下 jQuery 的原型關係圖,理解起來更加方便一些。
圖例:黃色的為對象,藍色的為函數。