一、Javascript中的對象有一個特殊的[[Prototype]]內置屬性,其實就是對於其餘對象的引用。幾乎全部的對象在建立時[[Prototype]] 屬性都會被賦予一個非空的值。bash
二、當咱們獲取一個對象的值的時候,首先會執行默認的[[Get]]操做來講,若是沒法在對象自己找到須要的屬性,就會繼續訪問對象的[[Prototype]]鏈函數
三、全部普通的[[Prototype]]鏈最終都會指向內置的Object.prototype.ui
四、若是咱們想給一個對象賦值的時候,這個屬性既出如今myObject中也出如今myObject的[[Prototype]]鏈上層,那麼就會發生屏蔽。若是不存在myObject上而是存在原型鏈上,會出現下面這些狀況。spa
myObject.foo = 'bar'
複製代碼
[[Prototype]]鏈上層
存在名爲foo的普通數據訪問屬性
而且沒有被標記爲只讀
,那就會直接在myObject中添加一個名爲foo的新屬性,它是屏蔽屬性
只讀
,則沒法修改已有屬性
或者在myObject上建立屏蔽屬性
若是但願上面二和三條也發生屏蔽,就不能使用=
操做符來賦值,而是使用Object.defineProperty來向myObject添加foo。prototype
function Foo(){
}
Foo.prototype.constructor === Foo // true
var a = new Foo();
a.constructor === Foo // true 實際a上並無constructor,而是經過prototype來查找到的Foo的constructor
複製代碼
Foo.prototype默認有一個公有而且不可枚舉的屬性.constructor,這個屬性引用的是對象關聯的函數
.code
兩種方法把Bar.prototype關聯到Foo.prototype:對象
Bar.prototype = Object.create(Foo.prototype)
Object.setPrototypeOf(Bar.prototype,Foo.prototype)
複製代碼
instanceof 操做符的左操做數是一個普通的對象
,右操做數是一個函數
.判斷左側的對象是不是右側函數的實例。ip
isPrototypeOf 判斷左側對象是否出如今右側對象的[[prototype]]鏈中。原型鏈
getPrototypeOf(a) 獲取a的原型get
b.isPrototypeOf(c)
Object.getPrototypeOf(a)
複製代碼
Object.create的polyfill代碼(這個polyfill有一個問題,就是不支持第二個參數(屬性描述符))
if(!Object.create){
Object.create = function(o) {
function F(){}
F.prototype = o;
return new F();
}
}
var myObject = Object.create(anotherObject,{
b:{
enumerable:false,
writable:true,
configurable:false,
value:3
}
})
複製代碼