js面試題繼承的方法及優(yōu)缺點解答
說一說js繼承的方法和優(yōu)缺點?
要點: 原型鏈繼承、借用構(gòu)造函數(shù)繼承、組合繼承、原型式繼承、寄生式繼承、寄生組合式繼承、ES6 Class
答:
一、原型鏈繼承
缺點:
- 1.引用類型的屬性被所有實例共享
- 2.在創(chuàng)建 Child 的實例時,不能向 Parent 傳參
//原型鏈繼承
function Parent() {
this.parentPrototype = "parent prototype"
//驗證這種繼承方法的確定,如果父類示例中存在一個引用類型的屬性,將會被所有子類共享
this.parentObj = {
info: "我是 parent 引用屬性parentObj中的 info"
}
}
function Children() {
}
//將Children的原型對象指定為Parent的示例,通過原型鏈,將Parent中的屬性賦值給Children示例
Children.prototype = new Parent();
const a = new Children();
console.log(a.parentPrototype); // parent prototype
//缺點
const b = new Children();
//在a示例中改動繼承的引用屬性
a.parentObj.info = "我是a示例中 引用屬性parentObj中的 info"
//b與a示例共享引用屬性
console.log(b.parentObj.info); // 我是a示例中 引用屬性parentObj中的 info
二、借用構(gòu)造函數(shù)(經(jīng)典繼承)
優(yōu)點:
- 1.避免了引用類型的屬性被所有實例共享
- 2.可以在 Child 中向 Parent 傳參
缺點:
- 1.方法都在構(gòu)造函數(shù)中定義,每次創(chuàng)建實例都會創(chuàng)建一遍方法。
function Parent() {
this.parentPrototype = "parent prototype"
this.obj = {
info: "parent obj info"
}
this.fn = function () {
console.log("打印功能")
}
}
function Children() {
Parent.call(this);
}
const a = new Children();
console.log(a.parentPrototype); // parent ptototype
//缺點 此時Parent()會再次創(chuàng)建一個fn函數(shù),這個是沒有必要的
const b = new Children();
a.obj.info = "a obj info";
//優(yōu)點 避免了子類實例共享引用屬性
console.log(b.obj.info) // parent obj info;
三、組合繼承
優(yōu)點:
- 1.融合原型鏈繼承和構(gòu)造函數(shù)的優(yōu)點,是 JavaScript 中最常用的繼承模式。
function Parent() {
this.parentPrototype = "我是Parent 中的屬性"
}
//Parent中的方法,在原型上定義
Parent.prototype.pFn = function () {
console.log('我是Parent中的方法');
}
function Children() {
//Parent中的屬性仍然在構(gòu)造函數(shù)中繼承
Parent.call(this);
}
//將Children的原型對象賦值為 Parent實例,這樣Parent中的方法也能夠被Children繼承
Children.prototype = new Parent();
const c = new Children();
console.log(c.parentPrototype); //我是Parent 中的屬性
c.pFn(); //我是Parent中的方法
四、原型式繼承
缺點: - 1.包含引用類型的屬性值始終都會共享相應的值,這點跟原型鏈繼承一樣。
function objFn(o) {
o.objFnPrototype = "我是 objFnPrototype"
function F() {}
F.prototype = o;
return new F();
}
let a = objFn({
name: "name1"
});
console.log(a.name); //name1
console.log(a.objFnPrototype); //我是 objFnPrototype
五、寄生式繼承
缺點:
- 1.跟借用構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對象都會創(chuàng)建一遍方法。
function createObje(obj) {
let clone = Object.assign(obj); //接受到對象后,原封不動的創(chuàng)建一個新對象
clone.prototype1 = "我是新增的prototype1"; //在新對象上新增屬性,這就是所謂的寄生
return clone; //返回新對象
}
const parent = {
parentPrototype: "parentPrototype"
}
//c實例,就繼承了parent的所有屬性
let c = createObje(parent);
console.log(c.parentPrototype); //parentPrototype
六、寄生組合式繼承
優(yōu)點:
- 1.這種方式的高效率體現(xiàn)它只調(diào)用了一次 Parent 構(gòu)造函數(shù),并且因此避免了在 Parent.prototype 上面創(chuàng)建不必要的、多余的屬性。
- 2.與此同時,原型鏈還能保持不變;
- 3.因此,還能夠正常使用 instanceof 和 isPrototypeOf。
function inherProto(superType, subType) {
//拷貝一個超類的原型副本
let proto = {
...superType.prototype
};
//將原型的超類副本作為子類的原型對象,也就是第一種中的原型鏈繼承方式,只不過繼承的是超類原型的副本
subType.prototype = proto;
//這一步比較迷,官方的說法是,我們在拷貝超類的原型的時候,拷貝的proto對象,將會丟失默認自己的構(gòu)造函數(shù),也就是superType,
//所以我們這里將它的構(gòu)造函數(shù)補全為subType。貌似不做這一步也沒啥問題,但是缺了點東西可能會有其他的副作用,所以還是補上
proto.constructor = subType;
}
function Super() {
this.superProto = "super proto";
this.colors = ["red", "yelloy"];
}
function Sub() {
this.subProto = "sub proto";
this.name = "sub name";
//這里還是借用構(gòu)造函數(shù)的套路
Super.call(this);
}
Super.prototype.getName = function () {
console.log(this.name);
}
//這里要在定義完Super的屬性后執(zhí)行,因為繼承的是超類原型的副本,與Super.prototype是兩個對象,在這之后再改變Super.prototype,就已經(jīng)不會在影響到Sub所繼承的副本超類原型對象了
inherProto(Super, Sub);
let a = new Sub();
console.log(a.getName);以上就是js面試題繼承的方法及優(yōu)缺點解答的詳細內(nèi)容,更多關(guān)于js面試題繼承方法優(yōu)缺點的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Javascript中bind()方法綁定函數(shù)的使用與實現(xiàn)
這篇文章主要為大家介紹了Javascript中bind()方法綁定函數(shù)的使用與實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06
js c++ vue方法與數(shù)據(jù)交互通信示例
這篇文章主要為大家介紹了js c++ vue方法與數(shù)據(jù)交互通信示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
lodash內(nèi)部方法getFuncName及setToString剖析詳解
本篇章我們主要是通過了解lodash里的兩個內(nèi)部方法getFuncName方法和setToString方法,在實際開發(fā)中我們也可以借鑒方法的實現(xiàn)思路,在需要的時候簡單封裝一下,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09

