function parent (age) { this.age = age } parent.prototype.say = function () { console.log(this.age) } function sub (age, value) { parent.call(this, age) this.value = value } sub.prototype = Object.create(parent.prototype, { constructor: { value: sub, enumerable: false, writable: true, configurable: true } })
关于Class的语法推荐看这里:es6.ruanyifeng.com/#docs/class前端
ES6 的class能够看做只是一个语法糖,它的绝大部分功能,ES5 均可以作到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。可是它们仍是有区别的。es6
区别:express
能够继承原生构造函数编程
根据上面的区别,咱们一步步的看。函数
解决问题:post
function _checkType (obj, constructor) { if (!(obj instanceof constructor)) { throw new TypeError('Cannot call a class as a function') } }
解决问题:this
// 修改构造函数描述符 function defineProperties (target, descriptors) { for (let descriptor of descriptors) { descriptor.enumerable = descriptor.enumerable || false descriptor.configurable = true if ('value' in descriptor) { descriptor.writable = true } Object.defineProperty(target, descriptor.key, descriptor) } } // 构造class // constructor 表示类对应的constructor对象 // protoDesc 表示class内部定义的方法 // staticDesc 表示class内部定义的静态方法 function _createClass (constructor, protoDesc, staticDesc) { protoDesc && defineProperties(constructor.prototype, protoDesc) staticDesc && defineProperties(constructor, staticDesc) return constructor }
const Foo = function () { function Foo(name) { _checkType(this, Foo) // 先检查是否是new调用的 this.name = name } _createClass (Foo, [ // 表示在class内部定义的方法 { key: 'say', value: function () { console.log(this.name) } } ], [ // 表示在class内部定义的静态方法 { key: 'say', value: function () { console.log('static say') console.log(this.name) } } ]) return Foo }()
到这里class实现完成,验证一下。spa
const foo = new Foo('aaa')
可见say方法是不可枚举的。prototype
可见静态方法say是不可枚举的。3d
解决问题:
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not' + typeof superClass) } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }) if (superClass) { Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass } }
解决的问题:
能够继承原生构造函数
// 返回父类的this;若为null,则返回自身 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called") } return call && (typeof call === 'object' || typeof call === 'function') ? call : self }
const Child = function (_Parent) { _inherits(Child, _Parent) // 继承父类原型上的属性及静态方法的继承 function Child(name, age) { _checkType(this, Child) // 先使用父类实例对象this,再返回 const _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, name)) _this.age = age return _this } return Child }(Foo)
子类class实现完成。验证一下。
Child并无在自身定义静态方法,可是它的父类有定义。继承成功。
const Child = function (_Parent) { _inherits(Child, _Parent) function Child(name, age) { _checkType(this, Child) const _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, name)) _this.age = age return _this } return Child }(Array) const c = new Child('bbb', 12)
继承成功。
原文: https://juejin.im/post/684490...
最后,欢迎关注个人公众号:前端开发博客,每日分享新鲜技术文章。