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

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);
            }
        }
    }
}

    原文作者:瑶柱活到老供楼到老
    原文地址: https://www.jianshu.com/p/6c18968c317b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞