1. 程式人生 > >原型鏈之prototype/__proto__/constructor

原型鏈之prototype/__proto__/constructor

支持 實現 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