从原型链 –> 继承
ES5的继承
ES6的继承
原型链
ps:prototype叫做原型,理解为“公有属性/方法”
JS中没有类的概念,因此也就没有继承的说法。
因此,只能把构造函数看作类
本身公有属性里不存在的,需要顺着原型链找的属性/方法看作继承
如果硬要说的话,arr的valueOf方法继承自Object
arr的push方法不是继承来的,而是实例属性(因为arr是个数组,而push是数组本来就有的公有属性,但valueOf与数组无关)
把构造函数看作类
ES6之前,JS没有类的概念,因此只得把构造函数当做类
继承
继承可以使得子类具有父类所有的属性和方法。
ES5的继承
- 首先,声明一个父类Human 1234567function Human(name){this.name=name;}Human.prototype.say=function(){console.log('我叫'+this.name);}var stage = new Human('stage');
- 然后,声明一个子类Male 1234567function Male(){this.gender = "男性";}Male.prototype.hobby = function(){console.log("男生喜欢玩电动");}var Jack = new Male();
- 接着,让子类Male继承父类Human的私有属性 12345function Male(name,age){Human.call(this,name);//将父类的私有属性name传过来this.gender = "男性";this.age = age;}
现在,子类Male继承了父类Human的属性,只差让子类的 原型 链接到 父类的prototype
- 最后,让子类继承父类的公有属性(prototype) 12Male.prototype.__proto__ = Human.prototype;//Male的 原型 链接到 Human的 原型
至此,子类Male继承了父类Human的name
属性和say()
方法
最终写法:
兼容IE的继承
由于IE11以下不支持Male.prototype.__proto__ = Human.prototype
;所以这一句要改写成
因此,ES5兼容IE的继承写法
new做了些什么
var this = {}
产生一个空对象,且this指向这个空对象- this.proto = 构造函数.prototype【举例:var stage = new Human(‘stage’),则stage.proto === Human.prototype】
- 执行
构造函数.apply(this,arguments)
- return this(生成的对象)
ES6的继承
在ES6中,将私有属性写在constructor里面,公有属性写在外面
ES6中class的缺陷
在ES5中,类的私有属性和公有属性上都可以有属性(变量)
而在ES6中,公有属性上只能放方法(函数),如果要放属性(变量),非常麻烦,要用get