js的六種繼承方式
阿新 • • 發佈:2022-05-12
原型鏈繼承
重點:讓新例項的原型等於父類的例項。
特點:1、例項可繼承的屬性有:例項的建構函式的屬性,父類建構函式屬性,父類原型的屬性。
缺點:1、新例項無法向父類建構函式傳參。
2、繼承單一。
3、所有新例項都會共享父類例項的屬性。
function Parent(name) { this.name = name || '阿巴' this.say = function () { console.log(this.name); } } Parent.prototype.job = function () { console.log('my job is teacher'); } Parent.prototype.age = 24 function Child() { } Child.prototype = new Parent() let child = new Child() console.log(child.age); console.log(child.name);
建構函式繼承
重點:用.call()和.apply()將父類建構函式引入子類函式
特點:1、只繼承了父類建構函式的屬性,沒有繼承父類原型的屬性。
2、解決了原型鏈繼承缺點1、2、3。
3、可以繼承多個建構函式屬性(call多個)。
4、在子例項中可向父例項傳參。
缺點:1、只能繼承父類建構函式的屬性。
2、無法實現建構函式的複用。每次用每次都要重新呼叫。
3、每個新例項都有父類建構函式的副本,臃腫。
function Parent(name) { this.name = name || '阿巴' this.say = function () { console.log(this.name); } } Parent.prototype.job = function () { console.log('my job is teacher'); } Parent.prototype.age = 24 function Child(name) { Parent.call(this,name) } let child = new Child('zzzz') let child1 = new Child() // child.name='阿布' console.log(child.name); child1.say()
組合繼承
重點:結合了兩種模式的優點,傳參和複用
特點:1、可以繼承父類原型上的屬性,可以傳參,可複用。
2、每個新例項引入的建構函式屬性是私有的。缺點:呼叫了兩次父類建構函式(耗記憶體),子類的建構函式會代替原型上的那個父類建構函式。
function Parent(name){ this.name=name this.age=12 } function Child(name){ Parent.call(this,name) } Child.prototype=new Parent() let child=new Child('wl') console.log(child.name); console.log(child.age);
原型式繼承
重點:用一個函式包裝一個物件,然後返回這個函式的呼叫,這個函式就變成了個可以隨意增添屬性的例項或物件。object.create()就是這個原理。
特點:類似於複製一個物件,用函式來包裝。
缺點:1、所有例項都會繼承原型上的屬性。
2、無法實現複用。(新例項屬性都是後面新增的)
function createObj(o){ function F(){} F.prototype=o return new F() } let person={ name:'llm', age:23, say:function(){ console.log('AAAAA'); } } let person1=createObj(person) let person2=createObj(person) console.log(person1.say()); person2.age=24 console.log(person2.age); console.log(person1.age);
寄生式繼承
重點:用一個函式包裝一個物件,然後返回這個函式的呼叫,這個函式就變成了個可以隨意增添屬性的例項或物件。object.create()就是這個原理。
特點:類似於複製一個物件,用函式來包裝。
缺點:1、所有例項都會繼承原型上的屬性。
2、無法實現複用。(新例項屬性都是後面新增的)
function createObj(o){ function F(){} F.prototype=o return new F() } let person={ name:'llm', age:23, say:function(){ console.log('AAAAA'); } } let person1=createObj(person) let person2=createObj(person) console.log(person1.say()); person2.age=24 console.log(person2.age); console.log(person1.age);
寄生組合式繼承
重點:修復了組合繼承的問題
function Parent(name){ this.name=name; this.colors=['red','blue','green'] this.age=0 } Parent.prototype.getName=function(){ console.log(this.name); } function Child(name,age){ Parent.call(this,name); this.age=age; this.name=name; } // 關鍵的三步 // let F=function(){} // F.prototype=Parent.prototype // Child.prototype=new F() // 封裝一下 function object(o) { function F() {} F.prototype = o; return new F(); } function prototype(child, parent) { var prototype = object(parent.prototype); prototype.constructor = child; child.prototype = prototype; } // 當我們使用的時候: prototype(Child, Parent); let child1=new Child('lucky',18) let child2=new Child('lucky') console.log(child1,); console.log(child2);