js面試題繼承的方法及優(yōu)缺點(diǎn)解答
說一說js繼承的方法和優(yōu)缺點(diǎn)?
要點(diǎn): 原型鏈繼承、借用構(gòu)造函數(shù)繼承、組合繼承、原型式繼承、寄生式繼承、寄生組合式繼承、ES6 Class
答:
一、原型鏈繼承
缺點(diǎn):
- 1.引用類型的屬性被所有實(shí)例共享
- 2.在創(chuàng)建 Child 的實(shí)例時(shí),不能向 Parent 傳參
//原型鏈繼承
function Parent() {
this.parentPrototype = "parent prototype"
//驗(yàn)證這種繼承方法的確定,如果父類示例中存在一個(gè)引用類型的屬性,將會(huì)被所有子類共享
this.parentObj = {
info: "我是 parent 引用屬性parentObj中的 info"
}
}
function Children() {
}
//將Children的原型對(duì)象指定為Parent的示例,通過原型鏈,將Parent中的屬性賦值給Children示例
Children.prototype = new Parent();
const a = new Children();
console.log(a.parentPrototype); // parent prototype
//缺點(diǎn)
const b = new Children();
//在a示例中改動(dòng)繼承的引用屬性
a.parentObj.info = "我是a示例中 引用屬性parentObj中的 info"
//b與a示例共享引用屬性
console.log(b.parentObj.info); // 我是a示例中 引用屬性parentObj中的 info
二、借用構(gòu)造函數(shù)(經(jīng)典繼承)
優(yōu)點(diǎn):
- 1.避免了引用類型的屬性被所有實(shí)例共享
- 2.可以在 Child 中向 Parent 傳參
缺點(diǎn):
- 1.方法都在構(gòu)造函數(shù)中定義,每次創(chuàng)建實(shí)例都會(huì)創(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
//缺點(diǎn) 此時(shí)Parent()會(huì)再次創(chuàng)建一個(gè)fn函數(shù),這個(gè)是沒有必要的
const b = new Children();
a.obj.info = "a obj info";
//優(yōu)點(diǎn) 避免了子類實(shí)例共享引用屬性
console.log(b.obj.info) // parent obj info;
三、組合繼承
優(yōu)點(diǎn):
- 1.融合原型鏈繼承和構(gòu)造函數(shù)的優(yōu)點(diǎn),是 JavaScript 中最常用的繼承模式。
function Parent() {
this.parentPrototype = "我是Parent 中的屬性"
}
//Parent中的方法,在原型上定義
Parent.prototype.pFn = function () {
console.log('我是Parent中的方法');
}
function Children() {
//Parent中的屬性仍然在構(gòu)造函數(shù)中繼承
Parent.call(this);
}
//將Children的原型對(duì)象賦值為 Parent實(shí)例,這樣Parent中的方法也能夠被Children繼承
Children.prototype = new Parent();
const c = new Children();
console.log(c.parentPrototype); //我是Parent 中的屬性
c.pFn(); //我是Parent中的方法
四、原型式繼承
缺點(diǎn): - 1.包含引用類型的屬性值始終都會(huì)共享相應(yīng)的值,這點(diǎn)跟原型鏈繼承一樣。
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
五、寄生式繼承
缺點(diǎn):
- 1.跟借用構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對(duì)象都會(huì)創(chuàng)建一遍方法。
function createObje(obj) {
let clone = Object.assign(obj); //接受到對(duì)象后,原封不動(dòng)的創(chuàng)建一個(gè)新對(duì)象
clone.prototype1 = "我是新增的prototype1"; //在新對(duì)象上新增屬性,這就是所謂的寄生
return clone; //返回新對(duì)象
}
const parent = {
parentPrototype: "parentPrototype"
}
//c實(shí)例,就繼承了parent的所有屬性
let c = createObje(parent);
console.log(c.parentPrototype); //parentPrototype
六、寄生組合式繼承
優(yōu)點(diǎn):
- 1.這種方式的高效率體現(xiàn)它只調(diào)用了一次 Parent 構(gòu)造函數(shù),并且因此避免了在 Parent.prototype 上面創(chuàng)建不必要的、多余的屬性。
- 2.與此同時(shí),原型鏈還能保持不變;
- 3.因此,還能夠正常使用 instanceof 和 isPrototypeOf。
function inherProto(superType, subType) {
//拷貝一個(gè)超類的原型副本
let proto = {
...superType.prototype
};
//將原型的超類副本作為子類的原型對(duì)象,也就是第一種中的原型鏈繼承方式,只不過繼承的是超類原型的副本
subType.prototype = proto;
//這一步比較迷,官方的說法是,我們?cè)诳截惓惖脑偷臅r(shí)候,拷貝的proto對(duì)象,將會(huì)丟失默認(rèn)自己的構(gòu)造函數(shù),也就是superType,
//所以我們這里將它的構(gòu)造函數(shù)補(bǔ)全為subType。貌似不做這一步也沒啥問題,但是缺了點(diǎn)東西可能會(huì)有其他的副作用,所以還是補(bǔ)上
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í)行,因?yàn)槔^承的是超類原型的副本,與Super.prototype是兩個(gè)對(duì)象,在這之后再改變Super.prototype,就已經(jīng)不會(huì)在影響到Sub所繼承的副本超類原型對(duì)象了
inherProto(Super, Sub);
let a = new Sub();
console.log(a.getName);以上就是js面試題繼承的方法及優(yōu)缺點(diǎn)解答的詳細(xì)內(nèi)容,更多關(guān)于js面試題繼承方法優(yōu)缺點(diǎn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript中Map與Object應(yīng)用場景
這篇文章主要為大家介紹了JavaScript中Map與Object應(yīng)用場景的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
微信小程序本地緩存數(shù)據(jù)增刪改查實(shí)例詳解
這篇文章主要介紹了微信小程序本地緩存數(shù)據(jù)增刪改查實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05
JavaScript日拱算法題解滑動(dòng)窗口的最大值示例
這篇文章主要為大家介紹了JavaScript日拱算法題解滑動(dòng)窗口的最大值實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
JavaScript使用JSON.stringify()方法帶參及不帶參示例詳解
這篇文章主要介紹了JavaScript使用JSON.stringify()方法帶參及不帶參示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07

