原型鏈之prototype/__proto__/constructor
阿新 • • 發佈:2017-07-21
支持 實現 typeof logs new reat 內部 引用 arp
(一)prototype
每個函數都有一個prototype屬性,這個屬性是指向一個對象的引用,這個對象稱為原型對象,原型對象包含函數實例共享的方法和屬性,也就是說將函數用作構造函數調用(使用new操作符調用)的時候,新創建的對象會從原型對象上繼承屬性和方法。
通過Function.prototype.bind方法構造出來的函數是個例外,它沒有prototype屬性
(二)__proto__
根據ECMA定義 ‘to the value of its constructor’s "prototype" ‘ ----指向創建這個對象的構造函數的顯式原型(prototype) 舉例說明:function A(){} A.prototype = {from:‘構造函數的prototype‘} var a = new A() a.__proto__ === A.prototype //true
每個對象都有一個內置屬性[[prototype]],在ES5之前沒有標準的方法訪問這個內置屬性,但是大多數瀏覽器都支持通過__proto__來訪問。ES5中有了對於這個內置屬性標準的Get方法Object.getPrototypeOf().
Object.prototype 這個對象是個例外,它的__proto__值為null
原型鏈的實現原理:當我們訪問一個對象的屬性時,如果這個對象內部不存在這個屬性,那麽他就會去__proto__裏找這個屬性,這個__proto__又會有自己的__proto__,於是就這樣 一直找下去。
(三)對象原型分析
剛剛已經講到,__proto__指向創建這個對象的構造函數的顯式原型,那麽關鍵我們只需要判斷該對象的構造函數prototype即可
1. 對象字面量
var a = {b:1}
//等效於 var a = new Object(); a.b=1;
a.__proto__ === Object.prototype //true
2. 構造函數創建的對象
function A(){} var a = new A()
a.__proto__ === A.prototype //true
3.Object.create() 創建的對象
var prop = {b:1} var a = Object.create(prop)
a.__proto__ === prop //true
(四)constructor
構造函數prototype對象會初始化一個constructor屬性,它指向的就是構造函數本身
function A(){} var a = new A()
a.__proto__.constructor === A.prototype.constructor A.prototype.constructor === A
所以,我們可以根據對象的constructor屬性,得到創建該對象的構造函數
原型鏈之prototype/__proto__/constructor