基于原型链与Class的继承

基于原型链的继承

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 父级构造函数
function Shape() {
this.x = 0;
this.y = 0;
}

// 父级构造函数的原型对象
Shape.prototype.move = function (x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
};

// 子级构造函数
function Rectangle() {
Shape.call(this); // 继承第一步:这里用call和apply都可以,目的是使子类实例具有父类实例的属性。
}

Rectangle.prototype = Object.create(Shape.prototype); //继承第二步:利用create把父级构造函数的原型对象添加到子对象的原型链上
Rectangle.prototype.constructor = Rectangle; //继承第三步:把子级构造函数的原型对象的constructor重新指回到子级构造函数上

这里有一个疑问,第二步为什么要用 create 而不是直接用Rectangle.prototype.__proto__=Shape.prototype呢? 因为__proto__并不被推荐直接使用,另外这里的 create 是ES6才出现的函数,如果要求必须使用ES5的话,那么第二步以及第三步可以使用以下代码代替:

1
2
3
var fn = function(){};
fn.prototype = Shape.prototype;
Rectangle.prototype = new fn()

基于 class 的继承

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 父级class
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
add() {
this.x += this.x;
this.y += this.y;
console.log(this.x, this.y);
}
}

// 子级class
class Son extends Father {
//第一步:使用extends关键词
constructor(x, y, z) {
super(x, y); //第二步:使用super来表示父类构造函数,用来新建父类的this
this.z = z;
}
sonadd() {
super.add();
this.z += this.z;
console.log(this.x, this.y, this.z);
}
}

注意点:

  • 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。
  • super方法的调用必须在constructor方法的首行。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!