接下來看一下陣列,其實也都一樣喔。以下建立一個純數字的簡單陣列:
const arr = [1, 2, 3, 4, 5];
console.dir(arr);
console.dir(Array);
console.dir(Object);
console.log(arr.__proto__ === Array.prototype); //true
console.log(arr.__proto__.__proto__ === Object.prototype); //true
console.log(arr.__proto__.__proto__.__proto__ === null); //true
用圖來說明:
其實函式跟陣列也是很像的。以下建立一個計算總和的函式:
const sum = function (a, b) {
return a + b;
};
console.dir(sum);
console.dir(Function);
console.dir(Object);
console.log(sum.__proto__ === Function.prototype);
console.log(sum.__proto__.__proto__ === Object.prototype);
console.log(sum.__proto__.__proto__.__proto__ === null);
用圖來說明:
函式sum的prototype:一般函式由Function constructor衍生,故其prototype是Function的prototype屬性。由圖中也可發現,因為sum由Function那繼承了各種Function method,所以可以在sum使用call(), bind()等等的方法。
函式sum的prototype的prototype:sum [[prototype]]本身是一個物件,由Object constructor衍生,故其prototype是Object的prototype屬性
函式sum的prototype的prototype的prototype:sum [[prototype]]的[[prototype]]裡已經沒有[[prototype]],所以這是prototype chain的終點:null
最後不知道大家會不會對於上面常常提到的各種build-in object的prototype感到好奇,就是像Object [[prototype]], Array [[prototype]]和Function [[prototype]],其實它們都指向同一個東西,就是Function的prototype屬性,我們來看一下:
console.log(Object.__proto__ === Function.prototype); //true
console.log(Array.__proto__ === Function.prototype); //true
console.log(Function.__proto__ === Function.prototype); //true
為什麼會這樣呢?還記得我們自定的建構函式是怎麼來的嗎?沒錯!就是用函式
定義出來的,而這些build-in object也是,所以它們的prototype是Function的prototype屬性。不然請大家自己去點開Object的[[prototype]],看看裡面是不是有一些函式方法像call()之類的。
這些例子雖然看起來很瑣碎,但其實到最後會發現,都是一樣的東西在重複,又是一個低腦容量學習法能派上用場的好機會。
udemy-The Complete Javascript Course
Prototype chain