关于 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

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

}

}

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容