Typescript类属性未初始化

时间:2018-04-16 11:40:54

标签: typescript

我有以下课程:

export abstract class LayerStyle {
    protected configuration: { [key: string]: string };
    protected style: ol.style.Style[];

    constructor(config: { [key: string]: string }) {
        this.configuration = config;
        this.createStyle();
    }

    protected abstract createStyle(): void;

    getStyle() {
        return this.style;
    }
}

及其子类:

import { LayerStyle } from './LayerStyle';

export class PointStyle extends LayerStyle {
    //default values
    FILL_COLOR = 'rgba(255,255,255,0.4)';
    STROKE_COLOR = '#3399CC';
    STROKE_WIDTH = 1.25;
    RADIUS = 5;

    createStyle() {
        let fillColor = this.FILL_COLOR;
        let strokeColor = this.STROKE_COLOR;
        let strokeWidth = this.STROKE_WIDTH;
        let radius = this.RADIUS;
        ...
    }
}

当我创建新的PointStyle let style = new PointStyle(styles).getStyle();时,它表示所有类变量(this.FILL_COLORthis.STROKE_COLORthis.STROKE_WIDTHthis.RADIUS)为空createStyle()内。为什么?难道它不能用它的属性创建类吗?我应该在子构造函数中初始化它们,然后使用super()调用父项吗?

1 个答案:

答案 0 :(得分:1)

问题是执行的顺序。字段初始值设定项只是构造函数中分配的字段的语法糖,但构造函数中执行的第一个语句是基础构造函数。如果我们查看生成的代码,问题会变得更加明确:

var PointStyle = /** @class */ (function (_super) {
    __extends(PointStyle, _super);
    function PointStyle() {
        // Super executed here !
        var _this = _super !== null && _super.apply(this, arguments) || this;
        //Field initialization here after createStyle is executed!
        _this.FILL_COLOR = 'rgba(255,255,255,0.4)';
        _this.STROKE_COLOR = '#3399CC';
        _this.STROKE_WIDTH = 1.25;
        _this.RADIUS = 5;
        return _this;
    }
    ...
    return PointStyle;
}(LayerStyle));
exports.PointStyle = P

调用构造函数中应该被覆盖的成员通常是一个坏主意,正是因为这种问题,你应该在派生类型中调用createStyle或者添加一个禁止执行createStyle的参数是从派生类调用:

export abstract class LayerStyle {
    protected configuration: { [key: string]: string };
    protected style: ol.style.Style[];

    constructor(config: { [key: string]: string }, callInit: boolean = true) {
        this.configuration = config;
        if(!callInit) this.createStyle();
    }

    protected abstract createStyle(): void;

    getStyle() {
        return this.style;
    }
}

export class PointStyle extends LayerStyle {
    constructor(config: { [key: string]: string }, callInit: boolean = true) {
        super(config, false);
        if(callInit) this.createStyle();
    }
    //default values
    FILL_COLOR = 'rgba(255,255,255,0.4)';
    STROKE_COLOR = '#3399CC';
    STROKE_WIDTH = 1.25;
    RADIUS = 5;

    createStyle() {
        let fillColor = this.FILL_COLOR;
        let strokeColor = this.STROKE_COLOR;
        let strokeWidth = this.STROKE_WIDTH;
        let radius = this.RADIUS;
    }
}