深入理解JavaScript原型和原型鏈

  在JavaScript中原型和原型鏈是很抽象的概念,對於大多數人也是最難理解的一部分,掌握原型和原型鏈的本質是JavaScript進階的重要一環。分享一下我對JavaScript原型和原型鏈的理解。

一、 函數對象

JavaScript 中,萬物皆對象。但對象也是有區別的,分爲:普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。

var myNewObject1 = {};//myNewObject1爲普通對象
        var myNewObject2 = new Object();//myNewObject2爲普通對象
        var myNewObject3 = new fun1();//myNewObject3爲普通對象

        function fun1(){};//fun1爲函數對象
        var fun2 = function(){};//fun2爲函數對象
        var fun3 = Function('str','console.log(str)');//fun3爲函數對象

        console.log(typeof Object);//function
        console.log(typeof Function)//function

        console.log(typeof fun1);//function
        console.log(typeof fun2);//function
        console.log(typeof fun3);//function

        console.log(typeof myNewObject1);//object
        console.log(typeof myNewObject2);//object
        console.log(typeof myNewObject3);//object

二、prototype__proto__的區別

prototype&&proto
2.1 prototype
定義:函數纔有的屬性

2.2 __proto__
定義:每個對象都有的屬性,但__proto__ 不是一個規範屬性,只是部分瀏覽器實現了此屬性,對應的標準屬性[[Prototype]]
注:大多數情況下__proto__ 可以理解爲“構造器的原型”
__proto__ === constructor.prototype
(如果一個對象是通過Object.create函數構造出來的,.那其proto就不一定是.constructor.prototype了)

var m = {};
console.log(m.prototype);  //undefined
console.log(m.__proto__);  //Object {}

var n = function(){}
console.log(n.prototype);  //n {}
console.log(n.__proto__);  //function() {}

三、 原型和原型鏈

3.1 原型
一個對象,其他對象可以通過它實現屬性繼承。

3.2 原型鏈
__proto__ 是任何對象都有的屬性,所以會形成一條__proto__ 連接起來的鏈條,遞歸訪問__proto__ 必須最終到頭,並且值爲NULL。自己是由自己創建的,好像不符合邏輯,但仔細想想,現實世界也有些類似,你是怎麼來的,你媽生的,你媽怎麼來的,你姥姥生的,……類人猿進化來的,那類人猿從哪來,一直追溯下去……,就是無,(NULL生萬物),正如《道德經》裏所說“無,名天地之始”。
當js引擎查找對象的屬性時,先查找對象本身是否存在該屬性,如果不存在,會在原型鏈上查找,而不會查找自身的prototype

var M = function(){};
var m = new M();
console.log(m.__proto__); //M {}(即構造器function M 的原型對象)
console.log(m.__proto__.__proto__); //Object {}(即構造器function Object 的原型對象)
console.log(m.__proto__.__proto__.__proto__); //null

總結

每個對象都有 proto 屬性,但只有函數對象纔有 prototype 屬性

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