原型继承
注:要深入了解原型继承需要先了解javascript原型链,不然下面会看的一脸懵逼
/**
* 原型链继承
* 实现方法:子类的prototype指向父类的一个实例对象
* 优点:多个子类可以复用父类的属性和方法
* 缺点:由于多个子类的prototype引用的都是父类相同的实例,所以子类的prototype、父类引用类型的属性,会被别的子类篡改;
*/
// 父类构造函数
function Person (job) {
this.job = job;
this.habit = ["eat", "drink", "sleep"];
}
// 父类增加方法
Person.prototype.printHabit = function () {
console.log(this.habit);
};
Person.prototype.printJob = function () {
console.log(this.job);
};
// 父类实例化对象
const person = new Person("people");
// 子类Student构造函数
function Student(name, job) {
this.name = name;
this.job = job;
}
// 子类Student的prototype指向父类Person的实例(实现继承)
Student.prototype = person;
// 子类Student增加方法
Student.prototype.printName = function () {
console.log(this.name)
};
// 子类Student实例化对象
const student = new Student("leo", "student");
// 子类Student的实例对象增加一个爱好(改变habit属性)
student.habit.push("read");
// 子类Teacher构造函数
function Teacher(name) {
this.name = name;
}
// 子类Teacher的prototype指向父类Person的实例(实现继承)
Teacher.prototype = person;
// 子类Teacher实例化对象
const teacher = new Teacher("MrLiu");
// 子类Teacher的实例对象增加一个爱好(改变habit属性)
teacher.habit.push("teach");
person.printHabit(); // ["eat", "drink", "sleep", "read", "teach"]
person.printJob(); // people
person.printName(); // undefined
console.log("------------------------------");
student.printHabit(); // ["eat", "drink", "sleep", "read", "teach"]
student.printJob(); // student
student.printName(); //leo
console.log("------------------------------");
teacher.printHabit(); // ["eat", "drink", "sleep", "read", "teach"]
teacher.printJob(); // people
teacher.printName(); // MrLiu
从打印结果可以看出子类都继承了父类的方法,由于子类Student在prototype新增了printName方法 所以 person student teacher 都具有了printName方法,也是因为他们共享的属性habit是引用类型的所以他们三个的habit都变化了。