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-06js c++ vue方法與數(shù)據(jù)交互通信示例
這篇文章主要為大家介紹了js c++ vue方法與數(shù)據(jù)交互通信示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08lodash內(nèi)部方法getFuncName及setToString剖析詳解
本篇章我們主要是通過了解lodash里的兩個內(nèi)部方法getFuncName方法和setToString方法,在實際開發(fā)中我們也可以借鑒方法的實現(xiàn)思路,在需要的時候簡單封裝一下,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09