【问题标题】:Typescript class properties not being initialized打字稿类属性未初始化
【发布时间】:2018-12-14 16:46:00
【问题描述】:

我有以下课程:

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(); 时,它会说 createStyle() 内的所有类变量 (this.FILL_COLOR,this.STROKE_COLOR,this.STROKE_WIDTH,this.RADIUS) 都为空。为什么?它不应该创建具有其属性的类吗?我应该在子构造函数中初始化它们,然后用super() 调用父级吗?

【问题讨论】:

  • 可以添加整个子类代码吗?构造函数不存在,必须是一个
  • 嗯。我认为它可以隐式扩展构造函数。

标签: typescript


【解决方案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;
    }
}

【讨论】:

  • 感谢您的解释。这就是我一直在寻找的 :) 这样我就可以正确地改变课程了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多