js的继承

一、原型链继承

将父类的实例作为子类的原型

javascript 复制代码
function Father(){
    this.name = 'Tony'
}

function Son() {}

Son.prototype = new Father()

let son = new Son();

console.log(son.name) // Tony

缺点:

  1. 父类所有的引用类型属性都会被所有子类共享,一个子类修改了属性值就会影响到其他子类。
  2. 子类不能给父类的构造函数传参

二、构造函数继承

在子类构造函数中调用父类构造函数并通过call或apply给父类传参、修改this指向。

javascript 复制代码
function Father(name){
    this.info = {
    name:name,
    job:'teacher'
    }
    this.sayName(){
       console.log(this.info.name)
    }
}

function Son (name){
    Father.call(this,name)
}

let s = new Son('Jerry');


let s2 = new Son ('Mike');


console.log(s.info.name) //Jerry

console.log(s2.info.name) // Mike

通过使用call()apply()方法,Parent构造函数在为Child的实例创建的新对象的上下文执行了,就相当于新的Child实例对象上运行了Parent()函数中的所有初始化代码,结果就是每个实例都有自己的info属性。

优点:

  1. 可以给父类传参
  2. 父类的引用类型不会被子类共享

缺点:

  1. 子类不能访问父类原型上定义的方法(prototype上挂在的方法)

三、组合式继承

组合式继承综合了原型链继承和构造方法继承的优点,通过原型链继承获得父类原型对象上的属性和方法。通过引用父类构造方法达到隔离子类共享属性,给父类传递参数 。

javascript 复制代码
function Father (name) {
   this.name=name
    
}

Father.prototype.sayName=function(){
    console.log(this.name)
}


function Son (name) {
    Father.call(this,name)
}
Son.prototype = new Father()
//手动挂载构造起,指向自己的构造方法
Son.prototype.constructor = Son

let s1 = new Son('Mike')

s1.sayName() // Mike

let s2 = new Son('Jerry')

s2.sayName() //Jerry

优点:

  1. 父类的方法可以复用
  2. 子类可以向父类传参
  3. 父类构造函数中的引用类型数据不会被共享

四、原型继承

对参数对象的一种浅复制 ,当Object.create()只有一个参数时与下面代码中的Object()方法相同

javascript 复制代码
let student = {
    hobbies:['music','football','basketball']
}

function Object (o) {
    function F(){}
    F.prototype=o
    return new F()
}

let s1 = Object(student)
s1.hobbies.push('sing')

console.log(s1.hobbies) //['music', 'football', 'basketball', 'sing']
let s2 = Object(student)
s2.hobbies.push('dance')
console.log(s2.hobbies) //['music', 'football', 'basketball', 'sing','dance']

优点:

  1. 父类方法可复用

缺点:

  1. 父类的引用会被子类共享
  2. 子类不能向父类传参

五、寄生试继承

寄生式继承是在原型继承基础上的拓展,类似于一个工厂模式,即创建一个用于封装继承的函数,该函数内部对参数对象做了增强。

javascript 复制代码
function Object (person){
    function F () {}
    F.prototype = person;
    return new F()
}


function createObject(person){

       let obj = Object(person)
       obj.sayHello = function(){
        console.log('hello')
       }

       return obj
}

let person = {
   name:'tony',
   age:32
}

let p1 = createObject(person)

p1.sayHello() //hello

p1.name //tony

六、寄生式组合继承

组合式继承有看似完美却有一个缺点,那就是父类的构造函数会被执行两次,一次是父类实例化时,一类是子类实例化时。这样就会造成内存没必要的消耗,寄生式组合继承正是弥补了这个短板,时目前最为理想的继承方式。

javascript 复制代码
function extend(subClass,superClass){
	var prototype = object(superClass.prototype);//创建对象
	prototype.constructor = subClass;//增强对象
	subClass.prototype = prototype;//指定对象
}

七、ES6继承

javascript 复制代码
class supClass {
    
    constructor(name) {
        this.name = name
    }
    sayName(){
       console.log(this.name)
    }
}

class subClass extends supClass{

    
    constructor (name) {
       super(name)
       this.name = name
    }
}


let sub = new subClass ('subClass')

console.log(sub.name)

sub.sayName() // subClass
相关推荐
云小遥6 分钟前
Cornerstone3D 2.x升级调研
前端·数据可视化
北执南念8 分钟前
JDK 动态代理和 Cglib 代理的区别?
java·开发语言
李明卫杭州11 分钟前
浅谈JavaScript中Blob对象
前端·javascript
springfe010112 分钟前
Cesium 3D地图 图元 圆柱 图片实现
前端·cesium
meng半颗糖14 分钟前
vue3 双容器自动扩展布局 根据 内容的多少 动态定义宽度
前端·javascript·css·vue.js·elementui·vue3
yt9483216 分钟前
jquery和CSS3圆形倒计时特效
前端·css3·jquery
teeeeeeemo17 分钟前
CSS3 动画基础与技巧
前端·css·笔记·css3
年纪轻轻就扛不住20 分钟前
CSS3 渐变效果
前端·css·css3
Aisanyi24 分钟前
【鸿蒙开发】使用HMRouter路由的使用
前端·harmonyos
杉木笙29 分钟前
Flutter 代码雨实现(矩阵雨)DLC 多图层
前端·flutter