美文网首页
理解JavaScript中的继承关系

理解JavaScript中的继承关系

作者: 左大人 | 来源:发表于2018-12-22 11:47 被阅读0次

原型概念

JavaScript的面向对象和Java有所区别,Java有类和实例的概念,类之间可以有继承关系,而在JS中,则是通过原型来实现面向对象编程。
JS中所有数据都可以看成对象,它没有Class的概念,要实现继承关系,只需要把一个对象的原型指向另外一个对象即可。

我们定义一个数组:

var arr = [1, 2, 3];

其原型链如下:
arr --> Array.prototype --> Object.prototype --> null

当我们创建一个函数:

function foo() {
    return 0;
}

它的原型链如下:
foo --> Function.prototype --> Object.prototype --> null

当我们访问一个对象的属性或方法时,JS引擎现在当前对象上查找该属性,如果没有找到,则在原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,最后还没有找到,就返回undefined注意不要把原型链搞的太长,会让访问对象属性变慢

继承的几种形式

这里主要介绍两种继承形式,原型继承class继承

1. 原型继承

现在有一个场景,定义了一个Student对象:

'use strict';
//通过构造方法实现Student
function Student(props) {
    this.name = props.name || 'Noname';
}
Student.prototype.hello = function() {
    alert('Hello, ${this.name}!');
}

然后我想定义GoodStudent来继承Student对象,通过原型模式可以按如下方式实现:

function GoodStudent(props) {
    Student.call(this, props);
    this.grade = props.grade || 50;
}

inherits(GoodStudent, Student);

GoodStudent.prototype.getGrade = function() {
    return this.grade;
}

//一个共用的原型继承方法
function inherits(Child, Parent) {
    var F = function() {};
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
}

下面,我们用一段代码验证是否如我们所愿:

//验证是否正确
var xiaoming = new GoodStudent({
    name: '小明',
    grade: '90'
});
//验证继承关系
console.log(xiaoming instanceof GoodStudent);
console.log(xiaoming instanceof Student);
//验证原型链
//通过xx.__proto__可以获取普通对象的原型,通过func.prototype可以获取构造方法的原型
console.log(xiaoming.__proto__ === GoodStudent.prototype);
console.log(xiaoming.__proto__.__proto__ === Student.prototype);

总结一下JavaScript原型继承实现方式:

  1. 定义新的构造函数,并在内容通过call()调用希望继承的构造函数,并绑定this
  2. 借助中间函数F实现原型链继承,最好通过封装好的inherits方法来完成
  3. 在新的构造函数的原型上定义新方法
下面,通过一张图来直观的看出他们之间原型链的关系: image.png

2. class继承

class关键字是从ES6开始被正式引入到JavaScript中的,目的就是为了让定义类更加简单。虽然通过原型可以实现继承,但需要编写大量的代码,而且理解起来比传统的类-实例要困难。
同样,我们还是想实现GoodStudent继承Student,下面是使用class的实现方式:

'use strict';
//通过class实现Student
class Student{
    constructor(name) {
        this.name = name;
    }
    
    //没有function关键字
    hello() {
        alert(`Hello, ${this.name}!`);
    }
}

接下来看一下GoodStudent的实现:

class GoodStudent extends Student {
    constructor(name, grade) {
        super(name); //通过super调用父类构造方法
        this.grade = grade;
    }

    getGrade() {
        alert(`My grade is ${this.grade}!`);
    }
}

//构造一个GoodStudent对象
var xiaoming = new GoodStudent('xiaoming', 90);

class的方式跟Java创建类和对象类似,更容易理解,而且代码也更加简洁。

总结

主要介绍了JS中的两种继承方式,class方式需要浏览器支持ES6,不过目前主流浏览器基本都支持了ES6,所以实现继承关系,可以优先考虑使用class方式。

相关文章

网友评论

      本文标题:理解JavaScript中的继承关系

      本文链接:https://www.haomeiwen.com/subject/yirikqtx.html