原型链继承
使用原型链实现继承的步骤如下:
- 定义父类型构造函数
- 给父类型的原型添加方法
- 定义子类型构造函数
- 创建父类型的对象并且赋值给子类型的原型
- 将子类型原型的构造属性设置为子类型本身
- 给子类型的原型添加方法
- 创建子类型的对象,能够调用父类型的方法
<script type="text/javascript">
// 1.定义父类型构造函数
function Father() {
this.fatherName = 'father';
}
// 2.给父类型的原型添加方法
Father.prototype.hello = function () {
console.log('I am ' + this.fatherName);
};
// 3.定义子类型构造函数
function Son() {
this.sonName = 'Son';
}
// 4.让子类型的原型指向父类型的一个实例对象
Son.prototype = new Father();// 原型链继承的核心就是子类型的原型为父类型的一个实例对象
// 5.将子类型的原型的constructor指向子类型本身
Son.prototype.constructor = Son;
// 6.给子类型的原型添加方法
Son.prototype.world = function () {
console.log('I am ' + this.sonName);
};
// 7.创建子类型的对象,调用父类型的方法
var son = new Son();
son.hello();// I am father
son.world();// I am Son
</script>
借用构造函数继承
使用构造函数实现继承的步骤如下:
- 定义父类型构造函数
- 定义子类型构造函数
- 在子类型构造函数中调用父类型构造函数
<script type="text/javascript">
// 1.定义父类型构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 2.定义子类型构造函数
function Student(name, age, score) {
// 使用构造函数实现继承的核心是在子类型构造函数中通用call()调用父类型构造函数
Person.call(this, name, age);// 相当于this.Person(name, age)
/*=name;
this.age=age;*/
this.score = score;
}
// 3.在子类型构造函数中调用父类型构造函数
var student = new Student('张三', 13, 89);
console.log(student.name, student.age, student.score);
</script>
组合继承
但通常是原型链和构造函数一起组合使用来实现继承:
- 利用原型链来实现对父类型对象的方法继承
- 利用
call()
借用父类型构造函数初始化相同属性。
<script type="text/javascript">
// 定义父类型构造函数并初始化属性
function Person(name, age) {
this.name = name;
this.age = age;
}
// 给父类型的原型添加方法
Person.prototype.setName = function (name) {
this.name = name;
};
// 定义子类型构造函数并初始化子类型和父类型的相同属性
function Student(name, age, score) {
Person.call(this, name, age);
this.score = score;
}
// 将子类型的原型指向父类型的实例对象,为了能够让子类型使用父类型的方法
Student.prototype = new Person();
// 修正子类型原型的constructor属性,让它指向子类型自身
Student.prototype.constructor = Student;
// 给子类型的原型添加方法
Student.prototype.setScore = function (score) {
this.score = score;
};
// 进行测试
var stu = new Student('张三', 18, 78);
stu.setName('李四');
stu.setScore(99);
console.log(stu.name, stu.age, stu.score);// 李四 18 99
</script>