js ES5实现继承
程序员文章站
2024-01-25 16:04:35
...
最近在准备面试题,发现挺多大厂都会问到用ES5实现继承这一问题,所以就收集这方面的资料把我认为讲的比较好的记录下来巩固记忆。
众所周知ES6之前并没有给我们提供extends继承的方法,但是我们可以通过构造函数+原型对象来模拟实现继承。接下来我会由浅入深的引出较为完善的实现继承的方法。
原型链图
方法1. 只继承属性,利用call改变this指向。
方法1的bug:该方法只可以继承属性,实例不可以使用父类的方法。
function Father(name) {//创建父类构造函数
this.name = name;
}
Father.prototype.eat = function () {//在父类的原型对象上添加一个公有方法
console.log('吃吃吃');
};
function Son(name, age) {//创建子类构造函数
Father.call(this, name);//调用父类构造函数并把this指向子类
this.age = age;
}
let son = new Son('儿子', 20);//实例化子类
son.eat(); //报错
为了解决不能继承父类的方法的问题,衍生出了方法2如下
方法2. 利用Son.prototype = Father.prototype改变子类原型指向父类原型的地址
方法2的bug:但此时我们给子类增加原型方法会影响到父类,使父类也增加了这个方法。
function Father(name) {
this.name = name;
}
Father.prototype.eat = function () {
console.log('吃吃吃');
};
function Son(name, age) {
Father.call(this, name);
this.age = age;
}
Son.prototype = Father.prototype;//子类原型对象指向父类的原型对象的地址
Son.prototype.drink = function () { //为子类添加方法
console.log('喝喝喝');
};
let son = new Son('儿子', 20);
son.eat()//"吃吃吃"
//此时父类也被影响了drink方法也在父类中
console.log(Father.prototype) //{eat: ƒ, drink: ƒ, constructor: ƒ}
又为了解决子类增加方法会影响到父类的问题,衍生出了方法3如下
方法3. 子类的原型指向父类的实例,这样就可以顺着原型链找到父类的原型并且共享父类的方法。而在为子类添加原型方法的时候也不会影响父类,perfect~
function Father(name) {
this.name = name;
}
Father.prototype.eat = function () {
console.log('吃吃吃');
};
function Son(name, age) {
Father.call(this, name);
this.age = age;
}
Son.prototype = new Father();//子类原型对象指向父类的实例
Son.prototype.drink = function () { //为子类添加方法
console.log('喝喝喝');
};
let son = new Son('儿子', 20);
son.eat()//"吃吃吃"
//此时父类没有被子类影响
console.log(Father.prototype) //{eat: ƒ, constructor: ƒ}
下一篇: Mac上Git安装与配置