资讯专栏INFORMATION COLUMN

JavaScript继承理解:ES5继承方式+ES6Class继承对比

liaoyg8023 / 2505人阅读

摘要:寄生组合式继承的继承方式有多种主要有原型链继承借用构造函数组合式继承寄生式继承和寄生组合式继承。中利用定义类,实现类的继承子类里调用父类构造函数实现实例属性和方法的继承子类原型继承父类原型,实现原型对象上方法的继承。

JavaScript中实现继承

  在JavaScript中实现继承主要实现以下两方面的属性和方法的继承,这两方面相互互补,既有共享的属性和方法,又有特有的属性和方法。

实例属性和方法的继承:
目的:每个实例都有自己特有的属性和方法。特别是引用类型属性,如果被共享,所有实例都可修改引用类型属性,并且反应到所有实例中。

原型属性和方法的继承:
目的:在继承中实现属性和方法的共享。避免每创建一次实例,都要新建一次属性和方法。

ES5—寄生组合式继承

  ES5的继承方式有多种:主要有原型链继承、借用构造函数、组合式继承、寄生式继承和寄生组合式继承。寄生组合式继承集组合式继承和寄生式继承的优点于一身,是ES5中,基于类型继承的最有效方式。
  接下来基于寄生组合式继承对ES5实现继承的方面进行解释。

//父类
function SuperType(name){
    //父类实例属性
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
//父类原型方法
SuperType.prototype.sayName = function(){
    alert(this.name);
};
//子类
function SubType(name, age){
    SuperType.call(this, name);//1.借用构造函数:继承父类的实例属性;
    this.age = age;
}
//2.寄生式继承:将父类原型的副本强制赋值给子类原型,实现继承父类的原型方法。
inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function(){
    alert(this.age);
};

function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype); //创建父类原型的副本
    prototype.constructor = subType; //将该副本的constructor属性指向子类
    subType.prototype = prototype; //将子类的原型属性指向副本
}

  以上示例就是ES5中寄生组合式继承的一个例子,如何实现子类继承父类?

借用构造函数SuperType.call(this, name);:当new SubType()创建子类实例时,首先调用父类构造函数,实现了子类实例继承父类的实例属性和方法

寄生式继承inheritPrototype(SubType, SuperType);:将父类原型副本强制替换成子类原型(1.副本constructor指向子类;2.子类prototype指向副本),使得子类原型包含父类原型中的所有属性和方法,实现了原型属性和方法的继承。

ES6中Class继承

  ES5中通过函数创建类型并基于原型实现继承的方式与其他面向对象的语言相比确实比较另类,没有那么简单明了;ES6就提供了更加接近传统语言的写法,引入了类的概念。

通过class关键字定义类
class super{
    constructor(name,color){
        this.name=name;
        this.color=["red","blue","green"];
    }
    sayName(){
        alert(this.name);
    }
}
 1. constructor为构造函数,如果非显示创建构造函数,定义类时也会自动创建构造函数;
 2. 通过`this`定义的属性和方法属于实例属性和方法;否则都是定义在原型上的属性和方法;
 3. class类中定义的方法`constructor、sayName`都属于原型方法。
extends实现类的继承
class Person{
    constructor(name,color){
        this.name=name;
        this.color=["red","blue","green"];
    }
    sayName(){
        alert(this.name);
    }
}

class Student extends Person(){
    constructor(name,color,score){
        super(name,color);//调用父类构造函数,this指向子类
        this.score=score;
    }
    showScore(){
        alert(this.score);
    }
}

let stu1=new Student("xuxu",["white","black","pink"],90);
stu1.sayName();//"xuxu"
stu1.showScore();//90
 1. 子类构造函数中调用父类构造函数,实现了子类继承父类的实例属性和方法;
 2. 通过extends,子类原型继承父类原型上的属性和方法:
    - Student.__proto__=Person;//作为对象,子类原型等于父类(构造函数的继承)
    - Student.prototype.__proto__=Person.prototype;//作为构造函数,子类原型对象是父类原型对象的实例。
 3. 子类静态方法继承父类静态方法
    - 静态方法的定义:关键字static;
    - 调用方法:类名调用(而不是实例调用);
    - 普通方法中,super作对象表示父类原型(用来调用父类原型方法);
      静态方法中super作对象表示父类(用来调用父类静态方法)。
    - 普通方法中this指向实例对象;静态方法中hits指向当前子类。
prototype和__proto__相互关系

对象(实例和原型对象)有__proto__属性,构造函数有prototype属性,原型对象有constructor属性。
  假设class B extends A,实例对象分别是insB、insA:

A.prototype.constructor=A;//类的原型的构造函数指向类本身。

insA.__proto__=A.prototype;//类的实例的原型指向创建它的构造函数的原型。

B.__proto__=A;//作为对象,子类的原型等于父类

B.prototype.__proto__=A.prototype;//作为构造函数子类原型继承父类原型

insB.__proto__.__proto__=insA.__proto__;//子类实例的原型的原型指向父类实例的原型

总结

ES5中:

利用借用构造函数实现 实例属性和方法的继承

利用原型链或者寄生式继承实现 共享的原型属性和方法的继承

ES6中:

利用class定义类,extends实现类的继承;

子类constructor里调用super()(父类构造函数)实现 实例属性和方法的继承

子类原型继承父类原型,实现 原型对象上方法的继承

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/108117.html

相关文章

  • 为什么都说js 里面任何对象最终都继承了Object对象

    摘要:今天闲来无事,看见几行小字。又说所有对象,继承终是。强行押韵一波这首诗的意思就是说的我今天没有什么事情,然后无意中又在网上看到了任何对象都是从对象继承而来的这句话。一时兴起,便去验证这句话。 今天闲来无事,看见几行小字。又说所有对象,继承终是Obj。—— 强行押韵一波 这首诗的意思就是说的我今天没有什么事情,然后无意中又在网上看到了任何对象都是从Object对象继承而来的这句话。一时兴...

    Gemini 评论0 收藏0
  • es6class揭秘

    摘要:语法在中运行以下代码调试观察的值。以上的继承其实就是我们说的寄生式组合继承,也是中最常用的继承模式。 在es6中,新增了class关键字用于定义一个类,但是本质上并没有给javascript增加新的oop机制,因为javascript原型继承以及构造函数式声明使人感到晦涩难懂,添加class的目的就是为了掩盖它底层的机制,使得我们不用直接接触这些概念,相当于一个语法糖。 class语法...

    piapia 评论0 收藏0
  • 刷《一年半经验,百度、有赞、阿里面试总结》·手记

    摘要:在掘金上看到了一位大佬发了一篇很详细的面试记录文章一年半经验,百度有赞阿里面试总结,为了查漏补缺,抽空就详细做了下。 在掘金上看到了一位大佬发了一篇很详细的面试记录文章-《一年半经验,百度、有赞、阿里面试总结》,为了查漏补缺,抽空就详细做了下。(估计只有我这么无聊了哈哈哈) 有给出的或者有些不完善的答案,也尽力给出/完善了(可能有错,大家自行辨别)。有些很困难的题目(例如实现Promi...

    codeKK 评论0 收藏0
  • 刷《一年半经验,百度、有赞、阿里面试总结》·手记

    摘要:在掘金上看到了一位大佬发了一篇很详细的面试记录文章一年半经验,百度有赞阿里面试总结,为了查漏补缺,抽空就详细做了下。 在掘金上看到了一位大佬发了一篇很详细的面试记录文章-《一年半经验,百度、有赞、阿里面试总结》,为了查漏补缺,抽空就详细做了下。(估计只有我这么无聊了哈哈哈) 有给出的或者有些不完善的答案,也尽力给出/完善了(可能有错,大家自行辨别)。有些很困难的题目(例如实现Promi...

    NusterCache 评论0 收藏0
  • javascript继承 --- 图解 ES5继承 VS ES6继承

    摘要:继承的继承可以简单的认为就是上篇文章中的寄生组合继承模型几乎一模一样,只是在语法结构上多了和关键字,另外一个区别就是父类和子类通过连接。 ES5继承 VS ES6继承 前言 ES6 已经发展了很长时间里 javascript相对于其他例如java等是一门比较怪异的语言, 由于其历史原因其继承机制和对象生成方式被人诟病. ES6 的出现将彻底改变这一现状, ES6 引入了新的生成对象(类...

    陆斌 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<