原型链实现继承

原型链实现继承

1. 无继承代码

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
27
28
29
30
// 定义Person类
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.running = function () {
console.log("running");
};
Person.prototype.eating = function () {
console.log("eating");
};

// 定义Student类
function Student(name, age, sno, score) {
this.name = name;
this.age = age;
this.sno = sno;
this.score = score;
}

Student.prototype.running = function () {
console.log("running");
};
Student.prototype.eating = function () {
console.log("eating");
};
Student.prototype.studying = function () {
console.log("studying");
};

2. 实现继承方式一

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
27
28
// 定义Person类
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.running = function () {
console.log("running");
};
Person.prototype.eating = function () {
console.log("eating");
};

// 定义Student类
function Student(name, age, sno, score) {
this.name = name;
this.age = age;
this.sno = sno;
this.score = score;
}

// 方式一: 将Person的显示原型赋值给Student的显示原型
// 缺点: 子类,父类公用一个原型对象,子类后续的studying方法也会加到父类的原型对象上,并且属性没有继承
Student.prototype = Person.prototype;

Student.prototype.studying = function () {
console.log("studying");
};

3. 实现继承方式二

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
27
28
29
// 定义Person类
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.running = function () {
console.log("running");
};
Person.prototype.eating = function () {
console.log("eating");
};

// 定义Student类
function Student(name, age, sno, score) {
this.sno = sno;
this.score = score;
}

const p = new Person("aaa", 18);

// 方式二: 将Person的实例对象赋值给Student的显示原型,父类的方法和属性子类都可以继承
// 缺点: 多个Student的实例对象的name和age都是p对象的属性,不能定制化

Student.prototype = Person.prototype;

Student.prototype.studying = function () {
console.log("studying");
};

4. 实现继承方式三: 借用构造函数

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
27
28
29
30
31
// 定义Person类
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.running = function () {
console.log("running");
};
Person.prototype.eating = function () {
console.log("eating");
};

// 定义Student类
function Student(name, age, sno, score) {
// 借用构造函数继承
Person.call(this, name, age);

this.sno = sno;
this.score = score;
}

const p = new Person("aaa", 18);

// 缺点: 父类的构造函数会被调用二次, 子类的实例对象上会有两份父类的属性

Student.prototype = Person.prototype;

Student.prototype.studying = function () {
console.log("studying");
};

5. 最终解决方案: 寄生组合式继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 定义Person类
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.running = function () {
console.log("running");
};
Person.prototype.eating = function () {
console.log("eating");
};

// 定义Student类
function Student(name, age, sno, score) {
Person.call(this, name, age);
this.sno = sno;
this.score = score;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.studying = function () {
console.log("studying");
};