Javascript作为面向对象的弱类型语言,继承
也是它非常强大的特性之一。每每我们和面试官聊到JS中的原型
、原型链
,我们就很可能不可避免地聊到继承,为了更好地和面试官唠嗑呢,或者说为了更好地理解JS的特征,继承都是我们一定要弄明白的。什么是继承?我们在JS中如何实现继承呢?本文章列出了JS中的五种非常经典的继承方式
。
Javasciprt五大经典继承
1. 原型链继承
2. 构造函数继承
3. 组合继承
4. 寄生组合继承
5. class继承
1.原型链继承
/* 原型链继承实现开始 */
function Animal(name){
this.name = name
this.loveFood = ['apple','banana','potatoes']
}
Animal.prototype.sayLoveFood = function(){
console.log(this.loveFood)
}
function Dog(){}
Dog.prototype = new Animal()
/* 原型链继承结束 */
/* 以下是例子 说明原型链继承的缺点(实例的引用类型共用了)*/
var dog1 = new Dog()
var dog2 = new Dog()
dog1.loveFood.push('asd')
console.log(dog2.sayLoveFood())
打开控制台粘贴复制可以得出原型链继承
的用例结果
:
优点
:
- 容易实现
- 纯粹的继承关系,创建的实例是子类的实例也是父类的实例
- 父类的原型方法、原型属性子类都能访问到
缺点
:
- 原型对象的所有属性被所有实例共享了,引用类型共用了(最大缺点)。
- 无法实现多继承(毕竟Dog.prototype只有一个)
- 创建子类实例时,无法向父类构造参数传参
2.构造函数继承
/* 构造函数继承开始 */
function Animal(name){
this.name = name
this.loveFood = ['apple','banana','potatoes']
}
Animal.prototype.sayLoveFood = function(){
console.log(this.loveFood)
}
function Dog(name){
Animal.call(this,name)
}
/* 构造函数继承结束 */
/* 以下是例子 说明构造函数继承的缺点 */
var dog1 = new Dog()
dog1.sayLoveFood()
打开控制台粘贴复制可以得出构造函数继承
的用例结果
:
优点
:
- 可以实现多继承,在Dog构造函数用多次call继承需要继承的父类就好了
- 实例的引用类型不是共享的了
缺点
:
- 若是父类的函数不是定义在原型上的,那么创建实例的函数不是复用的
- 实例不是父类的实例
- 实例不能继承父类的原型属性/方法(最大缺点)
3.组合继承
/* 组合继承开始 */
function Animal(name){
this.name = name
this.loveFood = ['apple','banana','potatoes']
}
Animal.prototype.sayLoveFood = function(){
console.log(this.loveFood)
}
function Dog(name){
Animal.call(this,name)
}
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
/* 组合继承结束 */
优点
:
- 可以实现多继承
- 子类是父类的实例
- 把函数定义在父类的的原型上,函数就可以复用了
- 实例从父类继承的引用类型也不会共享 可以说是挺完美了
缺点
:
- 创建实例的时候父类构造函数被调用了两次(一次是call调用,一次是new Animal调用)
4.寄生组合式继承
/* 寄生组合式继承开始 */
function Animal(name){
this.name = name
this.loveFood = ['apple','banana','potatoes']
}
Animal.prototype.sayLoveFood = function(){
console.log(this.loveFood)
}
var f = function(){}
f.prototype = Animal.prototype
function Dog(name){
Animal.call(this,name)
}
Dog.prototype = new f()
Dog.prototype.constructor = Dog
/* 寄生组合式继承结束 */
实现原理:其实并不难,跟组合式继承差不多,只是多定义了一个函数f,把父类的prototype继承下来(为了把父类不在原型上的属性砍掉),这样后面子类继承的时候就不会调用两次父类构造函数了。
优点
: 可以说是完美了,该有的都有了
缺点
: 多定义了一个函数
5.class实现继承
class Animal {
constructor(name) {
this.name = name
}
getName() {
return this.name
}
}
class Dog extends Animal {
constructor(name, age) {
super(name)
this.age = age
}
}
var dog = new Dog('a',15)
console.log(dog.getName())
优点
: class其实只是用ES5的prototype实现继承的一个语法糖而已,但是class让继承结构更清晰了
缺点
: 无
更多class相关的内容可以参考阮一峰老师的ES6入门: es6.ruanyifeng.com/#docs/class
完结
以上就是javascript的五大经典继承拉,你学会了吗?欢迎点赞加收藏!!!
你们的支持是我创作最大的动力。