JS原型鏈詳解

好久沒寫博客了,比較忙,最近的話同事正好在研究原型鏈,我也順便自己複習了下,順便總結歸納,儘可能的寫的詳盡一些。下面這幅圖就是一個比較全面的原型鏈的圖,在圖中有兩個比較容易搞混的單詞,一個是 proto (隱式原型) 一個是prototype(顯式原型),這兩個名詞形成了原型鏈的愛恨情仇。

下面我們看下這兩個原型出自哪裏,比較重要

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

下面的圖片是從知乎上面弄下來的祖傳老圖,被我挖過來了

這裏寫圖片描述
下面總(chao)結(xi)了幾條原型的概念,然後就不難理解上面的這幅圖了
1 . 任何對象都擁有 proto(隱式原型) 屬性, 一般指向他們的構造函數的原型 (prototype) .

var a = new Array () 
// a 是一個數組對象 默認擁有__proto__ 屬性 
console.log(a.__proto__ === Array.prototype);  // true

2 . 原型鏈的頂端是Object.prototype,其 proto爲 null

console.log(Object.prototype.__proto__ === null); // true

3 . 所有函數都擁有prototype (顯式原型)屬性
同最上面的圖,實例(對象/構造函數new 出來的東西)存在proto,函數/方法存在prototype(萬物皆對象,也存在proto,指向下面的Function)

4 . 所有函數都是Function 的 實例

function fn () { 
}
// fn 是 Function 構造函數創建出來的 
console.log(fn.__proto__ === Function.prototype);  // true
console.log(obj.__proto__ === Object.prototype); // true
console.log(arr.__proto__ === Array.prototype);    // true 

5 . Object Function Array 本身也都是一個函數,由於是最常用的,所以JavaScript幫我們實現了

// 當我們通過構造函數的方式來創建一個對象 ,其本質也是new一個普通的函數
// 因此可以得出
console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype );  // true
console.log(Array.__proto__ === Function.prototype);    // true

6 . 原型對象中又擁有constructor屬性,該屬性指向函數本身,這個好理解(constructor爲構造器,不修改的情況下prototype.constructor等於自己)

console.log(Function.prototype.constructor === Function); // true
console.log(Object.prototype.constructor === Object);     // true
console.log(Array.prototype.constructor === Array);       // true

7 . 原型鏈 概念
如果想要找到一個對象的屬性,首先會先在自身查找,如果沒有,就會通過proto屬性一層層的向上查找,直到原型鏈的頂端 Object.prototype(proto: null),這種通過某種紐帶(proto)將對象之間形成一種繼承關係 這種關係呈現出一種鏈條的形狀 將這種鏈條稱之爲原型鏈

function foo(name) {
   this.name = name;
}
foo.prototype = {
    showName: function() {console.log(this.name)}
}

var zyc = new foo('zyc');
zyc.showName = function(){ console.log('superMan') };
zyc.showName();     // superMan

// 刪除了本身屬性,查構造函數的prototype,不行再去查Object和Function的prototype
delete zyc.showName; 
zyc.showName();    // zyc

8 . 根據第 6 條可以推論得:

console.log(fn.constructor===Function); // true 
// fn自身並沒有constructor屬性,所以他會順着原型鏈向上找
// fn.__proto__ 指向的是 Function.prototype 見第4
// Function.prototype.constructor  === Function
console.log(Function.constructor === Function); // true
console.log(Object.constructor === Function);   //true

9 . Function.prototype.proto === Object.prototype
Function是一個特殊的例子 他創造了所有的函數,但他自身就是也是一個函數 總不能自己創造自己吧 所以他的上級是 Object.prototype

參考資料:
繼承與原型鏈
JS原型鏈圖解教程
圖文並茂深入淺出完全理解JavaScript原型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章