前提你先完全理解了原型链以及new的作用,否则先补一补再来看。
继承
如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类“ 继承是类与类之间的关系,所以new 构造函数不是继承
继承的作用
子类具有父类的属性和方法
思考:es6之前,js没有类,也就没有继承,为什么说js有继承?
我认为这是个悖论,js真的没有继承,不管是es5还是es6。js的“继承”是通过原型模拟的,这当然是Brendan Eich设计的时候搞的,因为js当时是用于一些简单的操作,比如表单验证,如果设计类的话,对于这个语言来说太重了
因此,他就把new命令引入了Javascript,用来从原型对象生成一个实例对象。但是,Javascript没有"类",怎么来表示原型对象呢?
这时,他想到C++和Java使用new命令时,都会调用"类"的构造函数(constructor)。他就做了一个简化的设计,在Javascript语言中,new命令后面跟的不是类,而是构造函数。考虑到这一点,Brendan Eich决定为构造函数设置一个prototype属性。这是一个很高效的方法,不黑js了,这可还行。
类的定义
是创建对象的蓝图,描述了所创建的对象共同的属性和方法。通俗一点,能产生对象的叫做类 类提供了可重复使用性的好处。自行车制造商一遍一遍地重用相同的蓝图来制造大量的自行车。软件程序员用相同的类,即相同的代码一遍一遍地创建对象。
思考:那我们是否可以认为构造函数是类呢? 不是
你完全可以在运行时修改“类”。也就不存在专门作为“对象的模板”的“类”了
即使勉强把某些“确实用作构造函数的对象”当成所谓“类”,也无法回避:与 prototype 相比,它根本就不象是“对象的模板”啊。而 prototype ,它是直接用来复制的,顶天了是个“基本的对象”,也不是“类”。
js中的“继承”
所以,你应该懂了,js中的"继承"本质上是通过new 一个构造函数加上原型链模拟的,那么我们如何写出这么一个“继承”?
ES5
function 熊(name){
this.name = name //熊的自身属性
}
熊.prototype.say = function(){
console.log("我叫"+this.name+",我tm熊的力量") //熊的自身方法
return undefined
}
function 北极熊(name){
熊.call(this, name) //北极熊调用熊(构造函数)使北极熊的实例具有熊的自身属性
this.color = 'white' //北极熊的私有属性
}
北极熊.prototype.color = function(){
console.log('我是白色的熊')
}
var fn = function(){} //为什么要写3行,直接北极熊.prototype=new熊()不就好了吗?由于new的副作用,会call熊()这个构造函数,让实例的北极熊的那一层属性出现name,所以我们用一个空函数,让空函数的原型=熊的原型,这个空函数相当于没有公共属性的熊。
fn.prototype = 熊.prototype
北极熊.prototype = new fn() //相当于让北极熊的原型链上熊的原型
----------------------------------- //上面3行等于下面一行,由于IE不支持下面这种写法,所以我们使用上面这样,主要用到了new的作用
北极熊.prototype.__proto__=熊.prototype
然后直接使用就好了var xiongDa=new 北极熊('熊大')
ES6
class 熊{
constructor(name){ //熊的自身属性,constructor(构造)
this.name = name
}
say(){
console.log("我叫"+this.name+",我tm熊的力量") //原型链上的直接写在class上
return undefined
}
}
class 北极熊 extends 熊{ //extends北极熊的原型链上熊的原型。
constructor(name){
super(name) //super 超类= 熊.call(this, name) ,就是执行你继承的类的constructor
this.color = 'white'
}
color(){
console.log('我是白色的熊') //北极熊原型链上的方法
}
}
所以呢,前端一定要理解es5的写法,了解js的这样设计的目的,es6的类(class)不不是真正意义上的类,只是一个语法糖,本质上还是通过prototype模拟类,所以 js没有中,没有真正类,也就没有真正意义上的继承,希望以后大家以后说js的“继承”给它加上两个引号!