x-note
Search…
利用原型链实现继承
在 ES6 实现class关键字之前,JavaScript 只能通过一些特殊的方式实现继承的概念。
常见的有以下几种实现方式:
  • 临时变量
  • callapply改变上下文
  • 原型链
  • mixin
尽管前两种能够获得父类的属性和方法,但是childreni_instance instanceof parent_instance的结果为false
使用原型链实现继承:
1
function Parent() {
2
this.sayAge = function () {
3
console.log(this.age);
4
};
5
}
6
7
function Child(firstname) {
8
this.fname = firstname;
9
this.age = 40;
10
this.saySomeThing = function () {
11
console.log(this.fname);
12
this.sayAge();
13
};
14
}
15
Child.prototype = new Parent();
16
let child = new Child("zhang");
17
child.saySomeThing(); // zhang 40
18
console.log(child instanceof Parent); // true
Copied!
这种实现方式,中每个Parent实例的sayAge()方法实际上应该是共用的。 可以通过使用callapply改变上下文的方式改良。改良如下:
1
function Parent() {}
2
Parent.prototype.sayAge = function () {
3
console.log(this.age);
4
};
5
function Child(firstname) {
6
Parent.call(this);
7
this.fname = firstname;
8
this.age = 40;
9
this.saySomeThing = function () {
10
console.log(this.fname);
11
this.sayAge();
12
};
13
}
14
Child.prototype = new Parent();
15
let child = new Child("zhang");
16
child.saySomeThing(); // zhang 40
Copied!
还有点问题:
  1. 1.
    上述实现方式中,Parent实际上共创建了Child实例个数 + 1 个实例。
  2. 2.
    原型链上存在额外的属性
进一步结合 mixin 的方式改良:
1
function extend(Child, Parent) {
2
Child.prototype = Object.create(Parent.prototype);
3
Child.prototype.constructor = Child;
4
return Child;
5
}
6
function Parent(lastname) {
7
this.lastname = lastname;
8
}
9
Parent.prototype.sayAge = function () {
10
console.log(this.age);
11
};
12
function Child(firstname, lastname) {
13
Parent.call(this, lastname); // Mock super
14
this.firstname = firstname;
15
this.age = 40;
16
this.saySomeThing = function () {
17
console.log(this.lastname, this.firstname);
18
this.sayAge();
19
};
20
}
21
extend(Child, Parent);
22
var child = new Child("san", "zhang");
23
child.saySomeThing(); // zhangsan 40
Copied!
Copy link