15分钟深入了解JS继承分类、原理与用法(3)

class Child extends Parent{ name ='qinliang'; sex = "male"; static hobby = "pingpong"; //static variable constructor(location){ super(location); } sayHello (name){ super.sayHello(name); //super调用父类方法 } }

我们再来看看 babel 编译过后的代码中的 _inherit() 方法:

function _inherits(subClass, superClass) { //SuperClass必须是一个函数,同时非null 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: { // 并且定义了新属性,这里是重写了constructor属性 value: subClass, enumerable: false, // 并实现了该属性的不可枚举 writable: true, configurable: true } } ); if (superClass) // 实现类中静态变量的继承 Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

从这里我们就可以很明显的看出 ES6 中的 extend 语法,在内部实现继承时,使用的是寄生组合式继承。

下面我们来看看编译过后,除了 _inherit() 方法外的其他编译结果代码:

"use strict"; var _createClass = function () { // 利用原型模式创建自定义类型 function defineProperties(target, props) { // 对属性进行数据特性设置 for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { // 设置Constructor的原型属性到prototype中 if (protoProps) defineProperties(Constructor.prototype, protoProps); // 设置Constructor的static类型属性 if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { // 调用子类的方法之前会先调用父类的方法 // 默认从Function.prototype中获取方法 if (object === null) object = Function.prototype; // 获取父类原型链中的指定方法 var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); // 继续往上获取父类原型 if (parent === null) { return undefined; } else { // 继续获取父类原型中指定的方法 return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; // 返回获取到的值 } else { var getter = desc.get; // 获取原型的getter方法 if (getter === undefined) { return undefined; } return getter.call(receiver); // 接着调用getter方法,并传入this对象 } }; function _classCallCheck(instance, Constructor) { // 保证了我们的实例对象是特定的类型 if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // 在子类的构造函数中调用父类的构造函数 function _possibleConstructorReturn(self, call) { // 一参为子类的this,二参为父类的构造函数 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; } var Child = function (_Parent) { _inherits(Child, _Parent); function Child(location) { // static variable _classCallCheck(this, Child); // 检测this指向问题 // 调用父类的构造函数,并传入子类调用时候的参数,生成父类的this或者子类自己的this var _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, location)); _this.name = 'qinliang'; _this.sex = "male"; return _this; } _createClass(Child, [{ //更新Child类型的原型 key: "sayHello", value: function sayHello(name) { // super调用父类方法,将调用子类的super.sayHello时候传入的参数传到父类中 _get(Child.prototype.__proto__ || Object.getPrototypeOf(Child.prototype), "sayHello", this).call(this, name); } }]); return Child; }(Parent); Child.hobby = "pingpong";

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6515e5a3620f673ed67ea15e0d5c9f1b.html