在基类中分配的对象不会更改子类

时间:2019-06-27 12:25:47

标签: javascript typescript ecmascript-6

我想用下面的初始数据创建一个基类:

export abstract class Entity {
    constructor(data?) {
        if (data) {
            Object.assign(this, data);
        }
    }
}

具有如下子类:

export class Filter extends Entity{
      show = true
      constructor(filter?: Partial<Filter>) {
        super(filter);
    }
}

我面临的问题是,当我创建像new Filter({show:false})这样的对象时,会得到以下结果:

Filter {show: true}

stackblitz

基类中的对象未反映子类中的值。有什么想法为什么会这样?

2 个答案:

答案 0 :(得分:2)

之所以发生这种情况,是因为一旦代码被编译,子类属性的分配就会在父构造函数被调用后 发生,您可以通过使用打字稿操场在选项中设置并设置,定位到ES5

为简短起见,转码如下:

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Entity = /** @class */ (function () {
    function Entity(data) {
        if (data) {
            Object.assign(this, data);
        }
    }
    return Entity;
}());
exports.Entity = Entity;
var Filter = /** @class */ (function (_super) {
    __extends(Filter, _super);
    function Filter(filter) {
        var _this = _super.call(this, filter) || this;
        _this.show = true;
        return _this;
    }
    return Filter;
}(Entity));
exports.Filter = Filter;
new Filter({ show: false });

如您所见,相关的部分是,在执行父构造器之后,在过滤器的构造器中,为show属性分配了

var Filter = /** @class */ (function (_super) {
    __extends(Filter, _super);
    function Filter(filter) {
        var _this = _super.call(this, filter) || this;
        _this.show = true;
        return _this;
    }
    return Filter;
}(Entity));

要解决此问题,您应该重新设计代码,并确保在构造函数中而不是在类声明中分配属性,而将类声明留空:

export abstract class Entity {
    constructor(data?) {
        if (data) {
          Object.assign(this, data);
        }
    }
}

export class Filter extends Entity{
      public show: boolean;
      constructor(filter?: Partial<Filter>) {
        super(filter);
        this.show = (this.show === undefined) ? true : this.show;
        console.log(this);
    }
}

new Filter({show:false}); // show is false
new Filter(); // show is true (default value)

工作代码:https://stackblitz.com/edit/typescript-c4u557

另一种可能的方法是,Entity类应具有一个带有默认值的show属性,但是从显示的层次结构来看,这似乎并不是您想要的。

答案 1 :(得分:0)

之所以会这样,是因为您在派生类中将show变量设置为true。因此它覆盖了基类的值。为了避免这种情况,您应该删除初始化值:

export class Filter extends Entity{
      show;
      constructor(filter?: Partial<Filter>) {
        super(filter);
        console.log('Filter', this)
    }
}