引言
其實很早我就接觸了原型鏈,可是一直是似懂非懂,實習或者是做項目經常性寫一些業務代碼也沒有用上,但是原型鏈這個東西是JavaScript的精髓,我一定要弄懂,嚶嚶嚶
話不多說開始吧
首先需要看一張相當經典的圖!
這張圖看起來有點亂,但其實條例時十分清晰的。
對象、函數以及原型之間的關係
對象:在JavaScript中,人和事是存在的東西都是對象(包括函數也是一個對象),我們平時new出來的對象,看似是由函數實例出來的,但是其實是個假象。
第一個概念:JavaScript中的所有對象並不是說是構造函數實例化(new)而來的,JavaScript中存在構造函數的概念,但是實例化是不存在的。其實JavaScript對象是產生於構造函數的原型屬性中
但是對象並不等於構造函數的原型屬性,他們並不是相等的。
var A=function(){
}
var a=new A();
console.log(a===A.prototype)//輸出false
oh~那麼那麼它們是個什麼關係呢?據資料講,這個關係造作克隆,每個對象都會有一個,JavaScript中給我們保留了一個屬性去維持這個關係,
那就死__proto__。
var A=function(){
}
var a=new A();
console.log(a.__proto__===A.prototype)//輸出true
這也就是爲什麼,我們在構造函數的原型屬性上寫的方法和屬性能夠被當前創建的對象訪問的原因,這個__proto__起了十分大的作用。
原型鏈
console.log(typeof A.prototype);//輸出object
繼續之前的例子,我們輸出A的原型屬性,發現是個object,對象!!那麼跟之前有類似了,他的構造函數是誰?
console.log(A.__proto__===Function.prototype);//輸出true
console.log(A.__proto__.__proto__===Object.prototype);//輸出true
就這樣一條原型鏈就能夠順清楚了。
console.log(Object.prototype.__proto__);//null
原型鏈的最頂端是null!
其實執行typeof null
也會是對象,其實它不僅僅是對象,他還是整個JavaScript體系的最上一級,所有的JavaScript對象都是由它一級一級克隆下來的!
補充一張圖片(見過最簡單易懂的圖了,但是注意,在原型鏈上查找的時候是不會查找自身的原型鏈的!):
拓展
我們將對象的創建再細化一下!
直接上例子看看:
/*1、字面量方式*/
var a = {};
console.log(a.__proto__); //Object {}
console.log(a.__proto__ === a.constructor.prototype); //true
/*2、構造器方式*/
var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}
console.log(a.__proto__ === a.constructor.prototype); //true
/*3、Object.create()方式*/
var a1 = {a:1}
var a2 = Object.create(a1);
console.log(a2.__proto__); //Object {a: 1}
console.log(a2.__proto__ === a2.constructor.prototype); //false(此處即爲圖1中的例外情況)
結語
啊哈哈哈哈哈哈哈哈哈哈終於把你順清楚了,你個原型鏈哈哈哈哈哈哈哈哈哈哈哈哈哈。
小建議就是,一定要自己動手!!印象更加深刻!!!!