HIHI,繼上一篇[筆記][JavaScript]物件間基本的原型鏈(1)講了Object.create()
的方式後,這次來提一下Object.setPrototypeOf()
,我覺得這個Object.setPrototypeOf()
物件函式會比Object.create()
還要來得靈活,因為Object.setPrototypeOf()
可以在兩個物件都存在時,直接指定一個物件給另一個物件當原型,不過這個物件函式的瀏覽器支援度比Object.create()
還要低多了,詳細的支援度可以參考這裡,主要是IE的部分,其他瀏覽器都差不多,大家也可以衡量一下需求做取捨,那現在來直接實作Object.setPrototypeOf()
看看。
//宣告一個A物件
var objA = {
writeNameA:function(){
console.log('objA is '+this.name);
},
};
//再宣告一個B物件
var objB = {
name:'B',
};
//現在我們用Object.setPrototypeOf()來實作繼承
//第一個參數要繼承物件,第二個參數為原型物件
Object.setPrototypeOf(objB,objA);
//繼承後objB就會有objA的特性了
objB.writeNameA(); //會印出'objA is B
//來試著使用Object.isPrototypeOf(obj)判斷原型
objA.isPrototypeOf(objB); //會回傳true
以上是Object.setPrototypeOf()
使用方式,但就像上一篇文章說的,每個物件的原型都只能有一個,所以如果對同一個物件重複設定原型,那前面設定的原型物件會被後來的物件原型蓋過去。
//多宣告一個C物件
var objC = {
writeNameC:function(){
console.log('objC is '+this.name);
},
};
//然後設定objC為objB的原型
Object.setPrototypeOf(objB,objC);
//宣告函式會發現objB的原型objA已經變成objC了
objB.writeNameC(); //會印出'objC is B
//然後我們去檢查他現在的原型是不是objA還是objC
objA.isPrototypeOf(objB); //會回傳false
objC.isPrototypeOf(objB); //會回傳true
雖然沒有辦法指定多個原型,但是就像上一篇說的,我們可以把objC設定為objA的原型,再把objA設定為objB的原型,讓objB同時有objA和objC的特性,形成一個原型鏈可以使用。
//首先設定objC為objA的原型
Object.setPrototypeOf(objA,objC);
//再設定objA為objB的原型
Object.setPrototypeOf(objB,objA);
//之後我們來調用從objA和objC繼承來的特性試試
objB.writeNameA(); //會印出'objA is B
objB.writeNameC(); //會印出'objC is B
//用Object.isPrototypeOf()來確認objB和objC是否在同一個原型鏈上
objC.isPrototypeOf(objB); //會回傳true
這篇的Object.setPrototypeOf()
和上一篇的Object.create()
不同的是他不需要在建立物件的同時指定原型,Object.setPrototypeOf()
也可以先建立好物件後,再替物件指定原型。
以上如果有說明錯誤或不明白的地方,麻煩再留言告知我,我會盡速改正!!
題外話,
可以請問一下,
rex是什麼?
rex是物件objB的name特性值
原諒我例子太爛了XD
不會啦,
只是覺得看不出這個字有什麼意義...
對阿rex有什麼意義嗎,我從上一篇就想問了XD
哈哈哈 不然我直接把它改成物件的名稱