前言
之前去某个大厂面试,等了大概20分钟,一个大腹便便的中年男子走过来了,一看就是典型的技术宅,心想肯定死的很惨
然后就开始了。
........
.......
......
面试官:你对es6类了解吗?
我:肯定了解啊,我使用angular8,天天都在和类打交道,比如 继承,实现接口,我都比较熟悉的
面试官:好的。嗯......那你给我讲一下es5的里的类继承方式吧
我:啊.......es5还有类的继承吗,不就是创建创建一个构造函数,然后在原型上创建一些属性和方法,实例就可以去使用,利用原型链去查找实现的。
面试官:我不是问你这个,我给你举个例子吧,比如有一个func A(){},有一个funcB(){},有哪些什么方法实现B继承A
我:好像可以使用call(this)去实现,其他的暂时不清楚
面试官:好吧.....嗯....... 那么你能给我讲讲call(this)存在的弊端吗?
我:(求你别问我这个了,我真的不知道,会结束面试吧)。嗯.......用的很少,不知道
面试官:好吧.....等通知吧,出去把门关上
我:好的.....出去那一刻,有种胸口被掏空的感觉
回去之后,就去查了相关的资料学习了一下,虽然这些都很少用,但是在面试的时候经常被问到,
所以总结了这篇文章。
es5创建一个类
function Animal(name){
this.name=name,
this.getName=function(){
return "动物的名字是:"+this.name
}
}
//创建实例
//es5使用function作为构造函数创建实例
var animal=new Animal('name')
console.log(animal.getName())//动物的名字是:name
es5在原型上创建function和属性
function Animal(name){
this.name=name,
this.getName=function(){
return "动物的名字是:"+this.name
}
}
Animal.prototype.age=null
Animal.prototype.getAge=function(){//声明原型上的function
return "动物的名字是:"+this.age
}
var animal=new Animal('name')
//当构造函数没有该属性时,会利用原型链逐级往上去查找,知道找到
//Animal的属性里没有age,就会去Annimal的原型上查找,正好找到了
animal.age=12
console.log(animal.getAge())//动物的名字是:12
es5里的静态属性和方法
function Animal(name){
this.name=name,
this.getName=function(){
return "动物的名字是:"+this.name
}
}
Animal.StaticFunc=function(){
return "我是一个静态方法"
}
console.log(Animal.StaticFunc())//我是一个静态方法
es5使用call实现对象冒充继承
//使用call实现对象冒充继承
function Animal(name){
this.name=name,
this.getName=function(){
return "动物的名字是:"+this.name
}
}
Animal.prototype.age=null
Animal.prototype.getAge=function(){//声明原型上的function
return "动物的名字是:"+this.age
}
function Dog(){
Animal.call(this,"Dog")
}
var dog=new Dog()
console.log(dog.getName())//动物的名字是:Dog
console.log(dog.getAge())//dog.getAge is not a function
注意点:对象冒充继承不能使用原型上的属性和方法,这是对象冒充的缺陷
ES5里原型链的继承,既可以实现构造函数的继承又可以实现原型链的继承
//使用原型链继承
function Animal(name){
this.name=name,
this.getName=function(){
return "动物的名字是:"+this.name
}
}
Animal.prototype.age=22
Animal.prototype.getAge=function(){//声明原型上的function
return "动物的名字是:"+this.age
}
function Dog(){
}
Dog.prototype=new Animal()//原型链继承
var dog=new Dog("dog")
console.log(dog.name)//undefined
console.log(dog.getAge())//动物的名字是:22
注意点:使用原型链继承虽然可以实现对原型方法的使用,但是不能实现对父类构造函数传参
思考
- 使用对象冒充继承虽然可以实现向父类传参,但是不能实现原型上的方法和属性
- 使用原型链继承可以实现原型上的方法和属性,但是不能向父类传参
- 基于以上两种继承都不完整,我们便想到对象冒充继承和原型链链继承混合实现
//使用原型链和对象冒充混合继承
function Animal(name){
this.name=name,
this.getName=function(){
return "动物的名字是:"+this.name
}
}
Animal.prototype.age=22
Animal.prototype.getAge=function(){//声明原型上的function
return "动物的名字是:"+this.age
}
function Dog(name){
Animal.call(this,name)
}
Dog.prototype= Animal.prototype//原型链继承
var dog=new Dog("dog")
console.log(dog.getName())//动物的名字是:dog
console.log(dog.getAge())//动物的名字是:22
最近研究es6的类,继承,接口实现,就先深入学习了es5的最原始的对象创建,类创建,类继承的一系列实现,
如果有错,请及时指出