js中的继承
1. 继承的概念
一个类继承父类的属性和方法。 ES6之前并没有专门用于继承的关键字。 ES6之后有了Class和extends。
2. 继承的作用
一类对象是包含另一类对象的。比如说,人肯定是包含老师的。老师肯定是一个人。人的属性老师肯定有。 为了体现两者之间的关系,就需要实现继承。
3. 实现继承的方法
在ES6之前有三种
3.1 使用原型链继承
重点: 将子类的原型对象 修改为 父类的实例对象。
Son.prototype = new Father();
缺点: 缺点:
1.对复杂数据类型(引用数据类型)的修改会出现误差
2.继承来的属性的值都是统一的。
// 公共属性
function Person(name, age) {
this.name = name;
this.age = age;
}
//老师
function Teacher(jobTitle, pay) {
this.jobTitle = jobTitle;
this.pay = pay;
}
// 老师继承公共属性
// 实例化公共对象
var P = new Person('小黑', 20);
// 每个实例化对象都有一个原型对象
// 将公共的原型对象赋值给老师的原型对象
Teacher.prototype = P;
// 实例化老师对象
var tea = new Teacher('体育老师', 2000);
// console.log(Teacher.prototype.name);
// console.log(Teacher.prototype.age);
console.log(tea.name); //tea实例化对象里面没有name属性,会向上找原型对象,这时person的实例化对象赋给了teacher的原型对象,所以teacher里面有name属性
console.log(tea.age); //和上面的name属性一样的原理
console.log(tea.jobTitle);
console.log(tea.pay);
console.log(tea);
3.2 借用构造函数继承
重点: 在子类的构造函数中,普通方式调用父类的构造函数,需要使用call或者apply来修改 构造函数的this指向。
function Son(param1,param2){
Father.call(this,param1,param2);
}
缺点:
1.继承来的方法只能定义在构造函数中,不能定义在父类的原型对象上
2.继承来的函数无法复用,占用内存比较大。
// 公共属性
function Person(name, age) {
this.name = name;
this.age = age;
this.eat = function() {
console.log("干饭人干饭魂,干饭都得用大盆");
}
}
//老师
function Teacher(name, age, pay) {
// 如果直接调用Person(),里面的this会指向window,所以需要下面的操作
// 强制this指向 是构造函数,this指向的是实例化对象tea
Person.call(this, name, age);
this.pay = pay;
}
var tea = new Teacher('离散', 12, 1000);
console.log(tea.name);
console.log(tea.age);
tea.eat();
console.log(tea);
3.3 组合继承(原型链与构造函数的组合)
组合继承:
结合了原型链继承和借用构造函数继承两者的优点;
步骤:
1.在子类的构造函数中借用父类的构造函数 father.call(this);
2.将父类的方法定义在父类的原型对象上。
3.将子类的原型对象指向 父类的实例对象
4.修正constructor属性。
function Person(name, age) {
this.name = name;
this.age = age;
this.emotion = ['喜', '怒', '哀', '乐'];
}
Person.prototype.eat = function() {
console.log('吃', '喝', '玩', '乐');
} //将父类的方法定义在父类的原型对象上。
function Teacher(name, age, pay) {
// 在子类的构造函数中借用父类的构造函数
Person.call(this, name, age); //这里的this指向的是Teacher的实例化对象
this.pay = pay;
}
Teacher.prototype = new Person(); //将子类的原型对象指向 父类的实例对象
Teacher.prototype.constructor = Teacher; //修正constructor属性. 如果不进行修正,Teacher.prototype.constructo指向了Person
var t1 = new Teacher('小张', '10岁', '1000元');
console.log(t1.name, t1.age, t1.pay, t1.emotion);
t1.eat();
t1.emotion.push('开开心心');
console.log(t1.emotion);
var t2 = new Teacher('小刘', '10岁', '2000元');
console.log(t2.emotion);