深入浅出js实现继承的7种方式

关注公众号 前端开发博客,回复“加群”

加入我们一起学习,天天进步

给大家介绍7中js继承的方法

有些人认为JavaScript并不是真正的面向对象语言,在经典的面向对象语言中,您可能倾向于定义类对象,然后您可以简单地定义哪些类继承哪些类(参考C++ inheritance里的一些简单的例子),JavaScript使用了另一套实现方式,继承的对象函数并不是通过复制而来,而是通过原型链继承

一、原型链继承

// 原型链实现继承
function Person(name,age) { this.name=name; this.age=age;
}
Person.prototype.show=function() {
    console.log(`我是${this.name},我今年${this.age}`)
} function Worker(name, age, job) {
    Person.call(this, name, age); this.job=job;
} // 如果此处有Woker的原型对象上的方法,由于原型重定向,下面的代码会覆盖此方法
Worker.prototype = new Person(); // 应该写在此处
Worker.prototype.showJob=function() {
        console.log(`我的工作是${this.job}`)
}; var mine = new Worker('佳', 18, '写代码');
console.log(mine);
mine.show();
mine.showJob();

存在的问题:

1.子类可以重写父类原型上的方法,Woker.prototype.proto.show=null, 此时已改变Person的原型对象上的方法;

2.父类的私有属性和公有属性都变成子类的公有属性;

  1. 如果子类的原型对象上原本有属性和方法,Woker.prototype = new Person()后,之前的方法无法再获取到;

解释原型重定向:  Woker.prototype = new Person();

1.自己开辟的堆内存中没有constructor属性,导致类的原型构造函数缺失(解决:自己手动在堆内存中增加constructor属性)

2.当原型重定向后,浏览器默认开辟的那个原型堆内存会被释放掉,如果之前已经存储了一些方法或者属性,这些东西都会丢失(所以:内置类的原型不允许重定向到自己开辟的堆内存,因为内置类原型上自带很多属性方法,重定向后都没了,这样是不被允许的)

二、借用构造函数继承

function Person(name, age){ this.name=name; this.age=age;
} function Worker(name, age, job){
      Person.call(this, name, age); this.job=job;
} var mine=new Worker('佳', 18, '写代码的');
console.log(mine);

优点:1. 相对于原型链而言,借用构造函数有一个很大的优势,即可以在子类型构造函数中向父类型构造函数传递参数。

缺点:1、只能继承父类构造函数的属性。

2、无法实现构造函数的复用。(每次用每次都要重新调用)

3、每个新实例都有父类构造函数的副本,臃肿。

三、组合继承(组合原型链继承和借用构造函数继承)(常用)

// 组合继承
function Person(name,age) { this.name=name; this.age=age;
}
Person.prototype.show=function() {
        console.log(`我是${this.name},我今年${this.age}`)
} function Worker(name, age, job) {
    Person.call(this, name, age); this.job=job;
}
Worker.prototype = new Person();
Worker.prototype.constructor = Worker;
Worker.prototype.showJob=function (){
    console.log(`我的工作是${this.job}`) }; var mine = new Worker('佳', 18, '打杂的');
console.log(mine);
mine.show();
mine.showJob();

重点:结合了两种模式的优点,传参和复用

优点:1、可以继承父类原型上的属性,可以传参,可复用。

2、每个新实例引入的构造函数属性是私有的。

缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。

四、原型式继承

// 原型式继承
function Woker(o){ function Empty(){};
    Empty.prototype = o; return new Empty();
} var mine = {
    name: 'jia',
    age: 18,
    job: '打杂的' }; var anotherMine =Woker(mine);

重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。

特点:类似于复制一个对象,用函数来包装。

缺点:1、所有实例都会继承原型上的属性。

2、无法实现复用。(新实例属性都是后面添加的)

var woker={
    name: 'jia',
    age: 18,
    job: '打杂的' } var mine = Object.create(woker);

原理和上面相同,ECMAScript 5 通过新增 Object.create()方法规范化了原型式继承。

Object.create:内置Object类天生自带的方法

1.创建一个空对象

2.让新创建的空对象的__proto__指向第一个传递进来的对象(把传入的对象作为新创建空对象的原型)

五、寄生式继承

// 寄生式继承
function createAnother(o) { var person = Woker(o);
    person.show=function() {
        console.log(`我是jia`)
        } return person;
} var mine = {
    name: 'jia',
    age: 18,
    job: '打杂的' }; var anotherMine = createAnother(mine);   

重点:就是给原型式继承外面套了个壳子。

优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。

缺点:没用到原型,无法复用。

也可用 Object.create()方法实现

六、寄生组合式继承

  //寄生组合式继承
function inheritProto(parents,child){ var o=Object.create(parents.prototype);
       o.constructor=child;
       child.prototype=o;
} //父类构造函数
function Parents(surname){ this.surname=surname;
}
Parents.prototype.getSurname=function(){
       console.log(this.surname);
} //子类构造函数
function Child(surname,age){
        Parents.call(this,surname); this.age=age;
}
inheritProto(Parents,Child);

Child.prototype.getAge=function(){
         console.log(this.age);
}

寄生组合式继承,集寄生式继承和组合继承的优点与一身,是实现基于类型继承的最有效方式。YUI 的 YAHOO.lang.extend()方法采用了寄生组合继承,从而让这种模式首次 出现在了一个应用非常广泛的 JavaScript 库中。要了解有关 YUI 的更多信息,请访问 http://developer. yahoo.com/yui/。

七、ES6的Class实现继承

class Person{
    constructor(name, age){ this.name=name; this.age=age;
    }
    show(){
        alert(this.name);
        alert(this.age);
    }
}

class Worker extends Person{
    constructor(name, age, job){
        super(name, age); this.job=job;
    }
    showJob(){
        alert(this.job);
    }
}
let me=new Worker('jia', 18, '前端攻城狮');
me.show();
me.showJob();

好啦,常见的7种JS继承的方法介绍完了。~~

转载:https://www.cnblogs.com/jiajialove/p/11264072.html

相关文章

  1. Javascript 里的奇葩知识

  2. 由浅入深,66条JavaScript面试知识点

  3. 20个常用的JavaScript简写技巧

最后

转发文章并关注公众号:前端开发博客,回复 1024,领取前端进阶资料

  1. 回复「电子书」领取27本精选电子书

  2. 回复「加群」加入前端大神交流群,一起学习进步

  3. 回复「JS」获取 JavaScript 精选文章

分享和在看就是最大的支持❤️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值