Vlastnosti třídy v Typescriptu nejsou inicializovány
Mám následující třídu:
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;
}
}
A jeho dětská třída:
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;
...
}
}
Když vytvořím nový PointStyle let style=new PointStyle(styles).getStyle();, říká to že všechny proměnné třídy (this.FILL_COLOR,this.STROKE_COLOR,this.STROKE_WIDTH,this.RADIUS) jsou uvnitř createStyle() null. Proč? Neměla by třída být vytvořena se svými vlastnostmi? Měl bych je inicializovat v konstruktoru potomka a pak volat rodiče s super()?
Odpověď č. 1
Problém je v pořadí provádění. Inicializátory polí jsou jen syntaktickým cukrem pro pole přiřazená v konstruktoru, ale prvním příkazem provedeným v konstruktoru je základní konstruktor. Pokud se podíváme na generovaný kód, problém se stává jasnějším:
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
Volání členů, které by měly být přepsány v konstruktorech, je obecně špatný nápad právě kvůli tomuto typu problémů, měli byste volat createStyle v odvozeném typu nebo přidat parametr, který potlačuje vykonávání createStyle, pokud je volán z odvozené třídy:
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;
}
}
