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

yan*_*rab 6 javascript typescript ecmascript-6

我想创建一个带有初始数据的基类,如下所示:

export abstract class Entity {
    constructor(data?) {
        if (data) {
            Object.assign(this, data);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有一个如下所示的子类:

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

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

Filter {show: true}
Run Code Online (Sandbox Code Playgroud)

堆栈闪电战

基类中的对象没有反映子类中的值。有什么想法为什么会发生这种情况?

bri*_*eje 7

发生这种情况是因为,一旦代码被转译,子类属性分配就会在调用父构造函数之后发生,您可以看到,通过使用打字稿游乐场并在选项中设置为 target 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 });
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,相关部分是,在 Filter 的构造函数中,属性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));
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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