原型继承

实际上,实现JavaScript的原型继承就如同Java的class中定义一个subclass一样,当我们定义了一个学生类Student,想要在定义一个子类去继承这个学生类,这就是原型继承,可是
由于JavaScript没有class类型,所以其中的一个方法就是借助一个空的函数F来实现正确的原型链,确保其原型指向是正确的。这个空函数F定义如下:

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
32
33
34
35
36
37
//子类的构造函数,在内部用call()调用希望“继承”的构造函数,并绑定this;
function PrimaryStudent(props){
Student.call(this,props);
this.grade = props.grade || 1;
}

//空函数F
function F() {
}

//把F的原型指向Student.prototype
F.prototype = Student.prototype;

//把PrimaryStudent的原型指向一个新的F对象,F对象的原型正好指向Student.prototype:
PrimaryStudent.prototype = new F();

//把PrimaryStudent原型的构造函数修复为PrimaryStudent:
PrimaryStudent.prototype.constructor = PrimaryStudent;

//定义属于这个PrimaryStudent自己的方法
PrimaryStudent.prototype.getGrade = function () {
return this.grade;
};

//创建xiaoming;
var xiaoming = new PrimaryStudent({
name:'小明',
grade: 80
});

//验证原型
xiaoming.__proto__===PrimaryStudent.prototype; //true
xiaoming.__proto__.__proto__===Student.prototype; //true

//验证继承关系
xiaoming instanceof PrimaryStudent; //true
xiaoming instanceof Student; //true

还可以写一个inherits(),将继承这个动作封装成函数,方便调用,简化代码

1
2
3
4
5
6
function inherits (Child,Parent) {
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}

现在可以调用这个函数来实现继承了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Student(props) {
this.name = props.name || '';
}

Student.prototype.hello = function () {
alert('hello,'+this.name+'!');
}

function PrimaryStudent(props){
Student.call(this,props);
this.grade = grade || 1;
}

//实现继承
inherits(PrimaryStudent,Student);

//定义PrimaryStudent自己的方法
PrimaryStudent.prototype.getGrade = function () {
return this.grade;
};

PS:以上是个人学习js面向对象的一些不成熟不全面的总结,想了解更多关于js面向对象的知识,推荐廖雪峰的js面向对象教程以及阮一峰的网络日志