在 JavaScript 中除了純值外其他東西都是物件,
物件的原型屬性可以參考另外一個物件的屬性與方法,
我們先新增一些空的物件、函數、陣列,
程式碼如下:
var a = {};
var b = function() {};
var c = [];
接著我們到 Console 中來看他們的原型屬性(物件),
在瀏覽器上我們可以在所有型別找到__proto__
屬性,這方便我們來看每個型別資料的原型屬性(物件),
實際開發上不要去修改__proto__
屬性,這只是瀏覽器提供給我們方便察看物件的原型屬性(物件)的語法糖,
我們先來看指派給變數 a 的空物件,
先把變數 a 印出來看,
會發現指派給變數 a 的空物件有一個原型屬性__proto__
如下圖:
當我們透過點(成員取用)運算子來取用物件時會看到有這些屬性與方法可以使用,
如下圖:
物件通常有這些屬性與方法,
實際上物件本身沒有這些屬性與方法可以使用,是透過原型鏈來查找到原型(屬性)物件的屬性與方法,
如下圖:
接著我們可以繼續透過點運算子取用原型屬性的屬性與方法,
會看到原型屬性有自己的原型屬性可以取用,
如下圖:
如果我們繼續透過點運算子取用空物件的原型屬性的原型屬性會發現已經沒有屬性與方法可以使用了,
如下圖:
現在空物件的原型屬性的原型屬性的值是 null
,
如下圖:
因此可以得知原型屬性 (物件) 的最下層是 null
接著可以來看指派給變數 b 的 函數,
如下圖:
會發現指派給變數 b 的 函數回傳一個空的函數給我們,
但透過點運算子來取用空的函數的屬性與方法時,會發現函數也有自己的原型屬性,
如下圖:
接著我們透過點運算子取用原型屬性(物件) 的屬性,會發現有我們之前談過的 bind 、apply 、call、arguments 等函數內建屬性與方法,
如下圖:
因此可以得知函數也會去自己的原型屬性(物件)中取用屬性與方法,
如果繼續取用函數的原型屬性的原型屬性會看到可以取用物件的屬性與方法,
這時原型屬性其實是一個最基本的物件,
如下圖:
如果我們透過點運算子繼續取用函數的原型屬性的原型屬性的原型屬性,
這時如果還想透過點運算子取用屬性與方法,會看到已經沒有可以取用的屬性與方法了,
如下圖:
因為這時已經查找到原型鏈最底層了,現在它的值是 null
,
如下圖:
因為查找原型鏈到最底層會得到 null
,
接著我們來看指派給變數 c 的陣列,
如下圖:
會發現指派給變數 c 的陣列也有一個原型屬性,
我們一樣透過點運算子取用陣列的屬性與方法,
會看到陣列一樣有自己的原型屬性,
如下圖:
接著我們取用陣列的原型屬性,
會看到原型屬性有許多屬性與方法,
如下圖:
這些原型屬性的屬性與方法不就是平我們操作陣列會用到的嗎?
因此可以得知在我們使用陣列的方法時,其實陣列本身並沒有這些屬性與方法,
都是到原型鏈查找原型屬性,來讓我們可以使用操作陣列的屬性與方法,
接著我們再繼續透過點運算子取用陣列的原型屬性時,原型屬性一樣有自己的原型屬性,
如下圖:
現在我們可以看到陣列的原型屬性自己的原型屬性有一些基本物件的屬性與方法,
如下圖:
這時他已經是一個最基本的物件,
如果們再透過點運算子取用基本的物件的原型屬性,
如下圖:
取用基本物件的原型屬性後會回傳值,
如下圖:
原型鏈最後會找到 null
,
現在我們有了一些對 JavaScript 的原型屬性認識,
在 JavaScript 中的字串、數值、布林、物件與 ES6 新推出的的型別 Symbol 都有原型屬性(物件),
可以在自己玩玩看,