前言
上文對原型和原型鏈做了一些簡單的概念介紹和解析,本文將淺析一些原型鏈的擴充套件。
擴充套件原型鏈
使用new操作符
利用原型是物件的特性,例項化物件的時候,繼承多個建構函式的屬性和方法
相容性:支援目前以及所有可想象到的瀏覽器 (IE5.5 都可以使用)
function parent1() {}
parent1.prototype = {
parentName: "parent1",
};
function parent2() {}
let child = new parent1();
child.childName = "child";
parent2.prototype = child;
let newChild = new parent2();
console.log(newChild.parentName); // parent1
console.log(newChild.childName); // child
使用Object.create
Object.create
Object.create() 方法建立一個新物件,使用現有的物件來提供新建立的物件的 proto
相容性:支援當前所有非微軟版本或者 IE9 以上版本的瀏覽器
/**
*
* Object.create(proto,[propertiesObject])
*
* @params proto 新建立物件的原型物件。
* 如果proto引數不是 null 或非原始包裝物件,則丟擲一個 TypeError 異常,可以使用try和catch捕獲丟擲的異常
*
* @params propertiesObject 可選引數 ,資料型別:物件
*
* */
const parent1 = {
name: "parent1",
do: function () {
console.log(this.name);
},
};
const child = Object.create(parent1);
child.name = "child"; // child新增自身的屬性name
child.do(); // child
/**
*
*
*
*---------------------------------------------------------------------------------------
*
*
* */
function parent2() {}
parent2.prototype = {
name: "parent2",
};
function parent3() {}
let child = Object.create(parent2.prototype);
child.childName = "child";
parent3.prototype = child;
let newChild = new parent3();
console.log(newChild.name); // parent2
console.log(newChild.childName); // child
使用setPrototypeOf
相容性:不支援 IE8 以下的版本。
/**
* Object.setPrototypeOf(obj, prototype)
*
* @params obj 要設定其原型的物件。
*
* @params prototype
*
* 該物件的新原型 (一個物件 或 null)
* 如果要設定原型的物件的 [[Prototype]] 被修改成不可擴充套件 (通過 Object.isExtensible()檢視),就會丟擲 TypeError 異常。
* 如果 prototype 引數的資料型別不是 物件或者 null (例如,數字,字串,boolean,或者 undefined),那麼方法就不會執行。
* 否則,該方法將 obj 的 [[Prototype]] 修改為新的值。
*
* Object.setPrototypeOf() 是 ECMAScript 6中新增的方法,相對於操作物件的原型鏈Object.prototype.__proto__來說,更適合拿來修改物件的原型
*
*
* */
function parent1() {}
parent1.prototype = {
name: "parent1",
};
function parent2() {}
let Obj = {
ObjName: "Obj",
};
Object.setPrototypeOf(Obj, parent1.prototype);
parent2.prototype = Obj;
let newChild = new parent2();
console.log(newChild.name); // parent1
console.log(newChild.ObjName); // Obj
使用__proto__直接在原型鏈上操作,
使用__proto__操作,如果設定的屬性和方法較多,會產生效能問題,因此不太推薦使用__proto__
相容性:IE10 及以下的瀏覽器版本。
/**
*
* 直接在原型鏈上操作,如果設定的屬性和方法較多,會產生效能問題
*
* */
var obj = {
__proto__: {
protoName1: "protoName1",
__proto__: {
protoName2: "protoName2",
__proto__: Object.prototype,
},
},
};
console.log(obj.protoName1); // protoName1
console.log(obj.protoName2); // protoName1
小結
- 在使用原型鏈編寫元件的過程中,我們需要考慮到原型鏈的效能問題。
- 例項化物件過程中,會向上查詢原型鏈的方法和屬性,在書寫的過程中,需要注意建構函式和物件的自帶的方法,確認是否會被覆蓋和重寫。
以上就是js中擴充套件原型鏈的簡單解析,有任何問題歡迎留言,後續的文章整理然後作為補充。
文章部落格地址:JavaScript擴充套件原型鏈淺析
原始碼地址
歡迎關注公眾號:程式設計師布歐,不定期更新一些文章
創作不易,轉載請註明出處和作者。