js原型继承--廖雪峰的官方网站

转载自廖雪峰的javascript教程

原型继承

在传统的基于Class的语言如Java、C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass。

由于这类语言严格区分类和实例,继承实际上是类型的扩展。但是,JavaScript由于采用原型继承,我们无法直接扩展一个Class,因为根本不存在Class这种类型。

但是基于js的原型特性,我们也可以实现继承。

1 function Student(props) {
2     this.name = props.name||'unNamed';
3 }
4 
5 Student.prototype.hello = function () {
6     alert('Hello, ' + this.name + '!');
7 }

我们先创建一个基于student扩展出来的primaryStudent,

1 function PrimaryStudent(props) {
2     // 调用Student构造函数,绑定this变量:
3     Student.call(this, props);
4     this.grade = props.grade || 1;
5 }

现在,primaryStudent的原型链是:

primarystudent-->PrimaryStudent.prototype-->object.prototype-->null

而我们要实现继承,即想要的得到的原型链是:

primarystudent-->PrimaryStudent.prototype-->Student.prototype-->object.prototype-->null

我们第一想到的是:

1 PrimaryStudent.prototype = Student.prototype;

但是这样不行,因为这样他两的原型是一样的,就不叫继承。

我们需要借助一个中间对象来实现正确的原型链,并且这个中间对象的原型要指向Student.prototype ,实现方法如下:

 1 // PrimaryStudent构造函数:
 2 function PrimaryStudent(props) {
 3     Student.call(this, props);
 4     this.grade = props.grade || 1;
 5 }
 6 
 7 // 空函数F:
 8 function F() {
 9 }
10 
11 // 把F的原型指向Student.prototype:
12 F.prototype = Student.prototype;
13 
14 // 把PrimaryStudent的原型指向一个新的F对象,F对象的原型正好指向Student.prototype:
15 PrimaryStudent.prototype = new F();
16 
17 // 把PrimaryStudent原型的构造函数修复为PrimaryStudent:
18 PrimaryStudent.prototype.constructor = PrimaryStudent;
19 
20 // 继续在PrimaryStudent原型(就是new F()对象)上定义方法:
21 PrimaryStudent.prototype.getGrade = function () {
22     return this.grade;
23 };
24 
25 // 创建xiaoming:
26 var xiaoming = new PrimaryStudent({
27     name: '小明',
28     grade: 2
29 });
30 xiaoming.name; // '小明'
31 xiaoming.grade; // 2
32 
33 // 验证原型:
34 xiaoming.__proto__ === PrimaryStudent.prototype; // true
35 xiaoming.__proto__.__proto__ === Student.prototype; // true
36 
37 // 验证继承关系:
38 xiaoming instanceof PrimaryStudent; // true
39 xiaoming instanceof Student; // true

将继承这个动作进行封装以简化代码和复用

 1 function inherits(Child, Parent) {
 2     var F = function () {};
 3     F.prototype = Parent.prototype;
 4     Child.prototype = new F();
 5     Child.prototype.constructor = Child;
 6 }
 7 
 8 function Student(props) {
 9     this.name = props.name || 'Unnamed';
10 }
11 
12 Student.prototype.hello = function () {
13     alert('Hello, ' + this.name + '!');
14 }
15 
16 function PrimaryStudent(props) {
17     Student.call(this, props);
18     this.grade = props.grade || 1;
19 }
20 
21 // 实现原型继承链:
22 inherits(PrimaryStudent, Student);
23 
24 // 绑定其他方法到PrimaryStudent原型:
25 PrimaryStudent.prototype.getGrade = function () {
26     return this.grade;
27 };

 

 

 

 

 

 

posted @ 2018-03-02 15:58  shuangcherry  阅读(316)  评论(0编辑  收藏  举报