javascript做为一门轻量级的脚本语言在ES6和node.js的横空出世以后将其推向的新的高度,虽然 ES6 中出现的新的生成对象的类语法格式,但依然为ES5的语法糖,而咱们依然有必要从javascript的原生实现入手来了解它的继承实现方式,ES6给出了更加简洁的固定的类声明方式,有兴趣的能够查看阮一峰的ES6入门,下面给出原文连接es6 阮一峰http://es6.ruanyifeng.comjavascript
javascript的继承不一样的开发者有不一样的理解方式,笔者认为主要分为四种
- 原型链继承 - 对象冒充继承(构造函数继承 不过我不喜欢这个名字) - 组合继承 - 寄生组合继承
对于继承,能够预先声明一个Animal, 进而讨论不一样的继承方式.
let Animal = (function () { function Animal (name) { this.name = name || 'Animal'; this.sleep = function(){ console.log(this.name + '正在睡觉!'); } } Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); } return Animal; })()
原型链继承java
let Cat = (function () { function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; return Cat; })()
原型链是 javascript 的典型继承方式, 这种继承方式的最大特色就是共享,全部事例共享原型对象中的全部属性和方法, 共享是它的最大优势 也是它的最大缺点, 正对咱们的不一样需求, 好比大多数状况下咱们经常须要某些属性是子类特有的 而一些读取属性方法须要共享,--另外此种继承没法向父类传参,没法实现多继承
对象冒充继承node
let Cat = (function () { function Cat(name){ Animal.call(this,name); } return Cat; })()
对象冒充继承就是简单的利用call或者apply方法实现继承,这种继承最大的特色正好与原型链继承相反不能继承原型属性/方法--非共享(子类自有一份), 一样这是它的优势也是它的缺点, 另外它解决了原型链继承中没法向父类传参的缺点, 而且能够实现某种意义上的多继承--(注意这种多继承是打引号的)
组合继承es6
let Cat = (function () { function Cat(name){ Animal.call(this, name); } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; return Cat; })()
组合继承是比较好的继承, 他是原型链继承和对象冒充继承的合体, 合理的利用了这两种组合的特色(是特色不是优势^_^),既是子类的实例,也是父类的实例, 但有一个缺点就是调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)形成内存浪费. 这也是用的最多的一种
寄生组合继承app
let Cat = (function () { function Cat(name){ Animal.call(this, name); } (function(sub, sup){ var Super = function(){}; Super.prototype = sup.prototype; sub.prototype = new Super(); sub.prototype.constructor = sub })(Cat, Animal) return Cat; })()
寄生组合继承是对组合继承的基础上的升华, 我的认为是堪称完美的继承方式,改进的组合继承内存浪费的问题^_^