原型概念
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原型继承实现方式:
- 定义新的构造函数,并在内容通过
call()
调用希望继承的构造函数,并绑定this
- 借助中间函数
F
实现原型链继承,最好通过封装好的inherits
方法来完成 - 在新的构造函数的原型上定义新方法

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方式。
网友评论