[[Prototype]] 可以理解為 prototype linkage(原型連接),是一種Javascript語言的機制。
prototype、constructor是某些對象上的屬性。
接下來可以通過一個函數(shù)開始理解
function Foo(name){
this.name = name;
}
Javascript內(nèi)部會創(chuàng)建一個Foo function, 該 Foo 會有一個prototype的屬性(所有的函數(shù)都會擁有一個名為prototype的公有并且不可枚舉的屬性),Foo.prototype會指向一個匿名對象,這個對象默認會有一個constructor屬性,這個屬性引用的是對象關聯(lián)的函數(shù),這個對象關聯(lián)的函數(shù)就是Foo。所以 Foo.prototype.constructor===Foo 的結果為true。
每一個普通對象都有內(nèi)置的Object.prototype,指向原型鏈的頂端。像toString()、valueOf()...這些方法都存在于Object.prototype對象上,因此語言中所有對象都可以使用它們。
Foo 函數(shù)也是對象,所以它Foo.prototype所指向的那個對象也會關聯(lián)到Object.prototype,這個就是所謂的原型鏈的最頂端。(原型鏈下面會解釋)
接下來再看一下代碼
Foo.prototype.whoIam(){
return "I am "+ this.name;
}
var a = new Foo('chen');
a.whoIam(); // 'I am chen'
new Foo() 會生成一個新對象,稱為a,這對象的內(nèi)部鏈接[[Prototype]]會關聯(lián)到 Foo.prototype上。實際上a并沒有whoIam,它會通過委托再Foo.prototype上找到。a對象為什么會有name屬性,通過this的綁定得到的(Foo function 里的 this.name=name)
那么其實就是在第一個對象上沒有找到需要的屬性或者方法引用,引擎就會繼續(xù)在[[Prototype]]關聯(lián)的對象上進行查找。同理后者也沒有找到需要的屬性或者方法引用就會繼續(xù)查找它[[Prototype]]關聯(lián)的對象上進行查找,如果一直找不到,最終查找到Object.prototype對象上。這一系列的行為就是所謂的原型鏈。
看完上面的圖之后就可以更好的理解下來的代碼了
a.constructor === Foo.prototype.constructor // true
a.constructor === Foo //true
實際上a 并沒有 constructor這個屬性,是a 通過[[Prototype]]關聯(lián)到了 Foo.prototype上,而Foo.prototype 上有constructor這個屬性,然后Foo.prototype.constructor引用的是Foo。
那么創(chuàng)建一個普通的a對象也是一樣的
var a = {};
a.constructor===Object.prototype.constructor //true