【前端知识之JS】JS如何实现继承
生活随笔
收集整理的這篇文章主要介紹了
【前端知识之JS】JS如何实现继承
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言
本系列主要整理前端面試中需要掌握的知識點。本節(jié)介紹JS如何實現(xiàn)繼承。
文章目錄
- 前言
- 一、什么是繼承
- 二、實現(xiàn)方式
- 1. 原型鏈繼承
- 2. 構(gòu)造函數(shù)繼承
- 3. 組合繼承
- 4. 原型式繼承
- 5. 寄生式繼承
- 6. 寄生組合式繼承(最優(yōu)繼承方法)
- 三、總結(jié)
一、什么是繼承
如果一個類別B繼承自另一個類別A,就把這個B成為A的子類,而把A成為B的父類,或者A是B的超類
繼承的優(yōu)點:
- 繼承可以使得子類具有父類的各種屬性和方法,而不需要再次編寫相同的代碼
- 在子類繼承父類的同時,可以重新定義某些屬性,并重寫某些方法,即覆蓋父類的原有屬性的方法,使其獲得于父類不同的功能。
二、實現(xiàn)方式
JS中常用的繼承實現(xiàn)方式為:原型鏈繼承、構(gòu)造函數(shù)繼承、組合繼承、原型式繼承、寄生式繼承、寄生組合式繼承。
1. 原型鏈繼承
原型鏈繼承中涉及到構(gòu)造函數(shù)、原型和實例,三者之間存在著一定的關(guān)系,即每一個構(gòu)造函數(shù)都有一個原型對象,原型對象又包含一個指向構(gòu)造函數(shù)的指針,而實例則包含一個原型對象的指針
function Parent(){this.name = 'parent1';this.play = [1,2,3] } function Child(){this.type = 'child2'; } Child.prototype = new Parent(); //Child是Parent的子類,Child繼承Parent console.log(new Child()); //包含Parent和Child中的所有屬性
但是,無論Child有多少個實例,他們的指針都是指向同一個地方的:
2. 構(gòu)造函數(shù)繼承
function Parent(){this.name = 'parent1'; }Parent.prototype.getName = function(){return this.name; }function Child(){Parent.call(this);this.type = 'child' }let child = new Child(); console.log(child); //正常輸出 console.log(child.getName()); // 報錯- 父類原型對象中一旦存在父類之前自己定義的方法,那么子類將無法繼承這些方法;
- 相比第一種原型鏈繼承方式,父類的引用屬性不會被共享,優(yōu)化了第一種繼承方式的弊端,只能繼承父類的實例屬性和方法,不能繼承原型屬性或者方法。
3. 組合繼承
function Parent(){this.name = 'parent';this.play = [1,2,3]; }Parent.prototype.getName = function(){return this.name; }function Child(){Parent.call(this);this.type = 'child'; } Child.prototype = new Parent(); var s1 = new Child(); var s2 = new Child(); s1.play.push(4); console.log(s1.play,s2.play); //互不影響 console.log(s1.getName()); //正常輸出 console.log(s2.getName()); //正常輸出這種寫法父類的引用屬性不會被共享,且能獲得原型的屬性或方法,缺點是Parent執(zhí)行了兩次,造成了多構(gòu)造一次的性能開銷。
4. 原型式繼承
let parent = {name:"parent",friends:['p1','p2','p3'],getName:function(){return this.name} };parent.getName = function(){return this.name; }let person1 = Object.create(parent); person1.name = "tom"; person1.friends.push("jerry");let person2 = Object.create(parent); person1.friends.push('lucy');console.log(person1.name); //tom console.log(person2.name); //parent console.log(person1.friends); //['p1', 'p2', 'p3', 'jerry', 'lucy'] console.log(person2.friends); //['p1', 'p2', 'p3', 'jerry', 'lucy']由于Object.create實現(xiàn)的是淺拷貝,多個實例的引用類型屬性指向相同的內(nèi)存,存在篡改的可能。
5. 寄生式繼承
let parent = {name:'parent',friends:['p1','p2','p3'],getName:function(){return this.name;} };function clone(original){let clone = Object.create(original);clone.getFriends = function(){return this.friends;}return clone; }let person = clone(parent) console.log(person.getName()); console.log(person.getFriends());優(yōu)缺點與原型式繼承一樣。
6. 寄生組合式繼承(最優(yōu)繼承方法)
function clone(parent,child){child.prototype = Object.create(parent.prototype);child.prototype.constructor = child; }function Parent(){this.name = 'parent';this.play = [1,2,3]; } Parent.prototype.getName = function(){return this.name; } function Child(){Parent.call(this);this.friends = 'child'; }clone(Parent,Child); Child.prototype.getFriends = function(){return this.friends } let person = new Child(); console.log(person); console.log(person.getName()); console.log(person.getFriends());extends可以直接實現(xiàn)繼承
class Person {constructor(name){this.name = name}getName = function(){console.log('Person:',this.name);} } class Gamer extends Person {constructor(name,age){super(name)this.age = age} } const asuna = new Gamer('Asuna',20) asuna.getName()三、總結(jié)
總結(jié)
以上是生活随笔為你收集整理的【前端知识之JS】JS如何实现继承的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 硬盘LBA 和CHS的关系(转)
- 下一篇: 千锋重庆web前端学习什么内容?