JavaScript的原型及原型鏈

    許多人對JavaScript的原型及原型鏈仍感到困惑,網上的文章又大多長篇大論,令讀者不明覺厲。本人小學時語文拿過全校第一名,我將用最簡潔明瞭的文字介紹JavaScript的原型及原型鏈。 函數

什麼是原型: this

    每個對象都有原型,使用 __proto__ 標記,原型是一個對象的引用或 nullObject.prototype 的原型爲 null ),容許對象使用其原型所引用的對象中的變量。 spa

var fun = function(){}

fun.prototype.a = 1;

var obj = new fun();

obj.a; //1


 

原型的來源: prototype

    對象的原型來自其構造函數的原型屬性(用 prototype 標記)的引用。注意原型與原型屬性是兩個概念。 code

    Function 爲實例( function )定義了原型屬性,其中包含一個構造函數(默認是 function 對象本身,用於構造 function 本身的實例),所以全部 function 都有原型屬性。Function 將本身的的原型屬性的引用做爲 function 的原型。 new 一個 function ,function 的實例便有了原型,指向 function 的原型屬性。 對象

有碼: 繼承

var fun = function(){

    this.a= 1;

}

fun.prototype.b = 2;

var obj = new fun();

obj.a; //1

obj.b; //2

 

有圖: ip

  

 解釋: 原型鏈

    上面的代碼定義了 fun 這個函數,其構造函數是 Function(),因此 fun 的原型就是 Function 的原型屬性。Function 還爲 fun 定義了屬於 fun 的原型屬性,因此 fun 既有原型又有原型屬性。 get

    咱們又爲 fun 的原型屬性定義了變量 b,因此能經過 fun 的實例 obj 找到 b,而 obj 由 fun 構造,因此 obj 被賦予了變量 a,這屬於 obj 本身。

    原型屬性也是對象,仍然有原型,是其構造函數的原型屬性的引用。

操做原型:

獲取原型:

    obj.__proto__; (IE 不支持)

    Object.getPrototypeOf(obj); (IE 8及如下不支持)

訪問原型的變量:

    除了以上兩種獲取原型方式,還能夠直接obj.attr;(不用我多說了吧)

修改原型的變量:

    沒法經過 obj.__proto__.attr = *; 或 Object.getPrototypeOf(obj).attr = *; 來修改原型的變量值,即沒法修改原型,屬於js內部特性。

    你只能經過修改對象的構造函數的原型屬性(prototype)來使對象的原型發生改變。如:

    fun.prototype.attr = *; 這將反應在 obj 上。

    假設對象的原型含有 attr 這個屬性,當經過 obj.attr 這種方式訪問原型的變量,默承認以在原型內搜尋到 attr 變量,若是企圖使用 obj.attr = *; 修改原型,js的處理方式是新建一個屬於 obj 的屬性 attr ,原型不會被修改(注意,若是 attr 是一個對象的引用,則指向的對象將會被修改)。再次訪問 attr ,並不會訪問到原型的 attr 變量。

原型的做用

    繼承。

    如:

 

var fun = function(){}

fun.prototype = String.prototype;

new fun().split //function split() {[native code]}

問題:每一個對象都有原型屬性嗎?

{}.prototype; //undefined

fun.prototype; // [object Object]

 

    函數有原型屬性而像{}new fun()這樣的非函數對象則沒有原型屬性(它們也不用去構造實例),但能夠手動爲其建立原型屬性,雖然這沒什麼意義。

    總而言之,原型屬性是其上級或者手動賦予的(fun.prototype = {}),不必定存在。做用是爲函數的實例提供構造方法及繼承變量。而原型是其構造函數的原型屬性,供對象使用。

原型鏈:

    經過本身的原型並向上尋找直到Object.prototype.__proto__; 這條鏈就是原型鏈。 

 

題外話:

    關於Function 與 Object 的關係,我暫時沒有去深究,但看如下代碼:

Function.prototype.constructor == Function //true

Function.constructor == Function //true

Object.constructor == Function //true

Object.getPrototypeOf(Object) == Object.getPrototypeOf(Function) //true

Object.prototype == Function.prototype //false

 

    從代碼看 Object 與 Function 都由相同的 constructor 建立 ,原型相同,但分配的原型屬性則不同。

    Object 由 Function 構造而來,Function 的原型屬性的構造函數即自身,這能夠理解,但 Function 的構造函數也是自身?這種語言的內部機制彷佛不必研究,但咱們要知道如何經過原型達到繼承的目的。

若有不妥,請大俠指正

相關文章
相關標籤/搜索