一、原型链方式
核心在于改造原型链,利用原型链的方法,实现了方法的继承。
Teacher.prototype = new Person();
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.speak = function (language) {
console.log('language', language)
}
function Teacher(name, age, subject) {
this.subject = subject;
}
// 注意这里不能使用Person.protype,而是需要创建对象
Teacher.prototype = new Person();
const teacher1 = new Teacher('张三', 21, '数学');
console.log('方法1', teacher1);
teacher1.speak('汉语')
二、 组合继承
原型链+构造函数组合的方式,发挥二者之长。
- 改造原型链,实现方法继承和1一致:
Teacher.prototype = new Person();
- 实例属性的构造过程没有复用,可以通过改变this指向来实例:
Person.call(this);
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.speak = function (language) {
console.log('language', language)
}
function Teacher(name, age, subject) {
// Person(); 调用之后this指向window,而不是当前的对象
Person.call(this, name, age)
this.subject = subject;
}
// 注意这里不能使用Person.protype,而是需要创建对象
Teacher.prototype = new Person();
const teacher1 = new Teacher('张三', 21, '数学');
console.log('方法2', teacher1);
teacher1.speak('英语')
三、寄生组合式继承
Object.create()
- 创建一个新对象;
- 这个新对象的_proto_指向传入的参数对象。
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.speak = function (language) {
console.log('language', language)
}
function Teacher(name, age, subject) {
// Person(); 调用之后this指向window,而不是当前的对象
Person.call(this, name, age)
this.subject = subject;
}
// Object.create
Teacher.prototype = Object.create(Person.prototype);
const teacher1 = new Teacher('张三', 21, '数学');
console.log('方法3', teacher1);
teacher1.speak('韩语')
四、ES6的class关键字
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
// 这个方法底层添加到prototype里去了
speak(language) {
console.log('language', language)
}
}
class Teacher extends Person {
// 如何没有构造函数,则new的时候自动调用父类构造函数
constructor(name, age, language) {
super(name, age);
this.language = language;
}
teach() {
console.log('教书')
}
}
const teacher = new Teacher('张三', 20, '日语')
console.log('teacher4', teacher)