美文网首页javascript基础学习NodeJS in LNNMJavascript精粹
关于 ES6 中的 Class 的几个特性和玩法

关于 ES6 中的 Class 的几个特性和玩法

作者: 瑶柱活到老供楼到老 | 来源:发表于2016-01-12 09:58 被阅读11477次

    1. 派生类的 constructor 必须显式定义:跟 C#、Java 等语言会默认创建调用父类构造逻辑的 constructor 不一样,ES6 的 Class 要求派生类明确写上 constructor 并在其中调用 super 函数以确保父类构造逻辑运行

    2. ES6 的 Class 在声明的时候,extends 的父类可以是运算结果,于是乎,相比起静态语言,可玩的东西很多,例如通过 Higer-Order Components 的模式来实现类似 mixin 的效果:

    'use strict';

    function helloSayable(Class) {
        return class extends Class {
            sayHello() {
                console.log('hello');
            }
        }
    }

    class A extends helloSayable(React.Component) {
    }

    const a = new A;
    a.sayHello(); // hello

    关于上边提到的 Higher-Order Components,推荐个文章:
    http://zhuanlan.zhihu.com/purerender/20361937
    React Mixin 的前世今生(内含 Higher-Order Components 的介绍)

    3. ES 6 的 Class 上的 static 成员在其派生类上将被包含:

    'use strict';

    class A {
        static methodOnA() {
            console.log('methodOnA');
        }
    }

    class B extends A {
    }

    class C extends A {
        static methodOnA() {
            console.log('methodOnA overrided by C');
        }
    }

    B.methodOnA(); // prints: methodOnA
    C.methodOnA(); // prints: methodOnA overrided by C

    这点超越了以往简单地通过 DerivedClass.prototype = new BaseClass() 的方式来实现继承达成的效果,实际上也确实更符合大家关于继承行为的预期,那具体底层做了什么呢?把上述代码在 Babel 中跑一趟后,从编译得的代码可以看出端倪,请留意加粗那段:

    'use strict';
    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;
    }
    function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
            throw new TypeError('Cannot call a class as a function');
        }
    }
    var A = function () {
        function A() {
            _classCallCheck(this, A);
        }
        A.methodOnA = function methodOnA() {
            console.log('methodOnA');
        };
        return A;
    }();
    var B = function (_A) {
        _inherits(B, _A);
        function B() {
            _classCallCheck(this, B);
            _A.apply(this, arguments);
        }
        return B;
    }(A);
    var C = function (_A2) {
        _inherits(C, _A2);
        function C() {
            _classCallCheck(this, C);
            _A2.apply(this, arguments);
        }
        C.methodOnA = function methodOnA() {
            console.log('methodOnA overrided by C');
        };
        return C;
    }(A);
    B.methodOnA();
    C.methodOnA();

    4. 跟 React.createClass 的情况不一样,ES6 的 Class 构造出来的对象上的方法默认不绑定到 this 上,所以传递时如果预期 this 不漂移,需要 bind(this) 一下再传,或者在 constructor 中对方法进行一遍替换,例如:

    class A extends React.Component {
        constructor() {
            super(...arguments);
            for (let i in this) {
                const method = this[i];
                if (method instanceof Function) {
                    this[i] = this[i].bind(this);
                }
            }
        }
    }

    相关文章

      网友评论

        本文标题:关于 ES6 中的 Class 的几个特性和玩法

        本文链接:https://www.haomeiwen.com/subject/epxckttx.html