Объект, назначенный в базовом классе, не меняет дочерний класс - PullRequest
3 голосов
/ 27 июня 2019

Я хочу создать базовый класс с начальными данными, как показано ниже:

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 ]

2 голосов
/ 27 июня 2019

Это происходит потому, что после переноса кода присваивание свойств дочернего класса происходит после того, как был вызван родительский конструктор, вы можете увидеть это, используя площадку для машинописного текста и задав в опциях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 });

Как вы можете видеть, соответствующая часть состоит в том, что в конструкторе фильтра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со значением по умолчанию, но не похоже, что вы хотите сделать это из иерархии, которую вы показали.

0 голосов
/ 27 июня 2019

Это происходит потому, что вы установили переменную show в true в своем производном классе. Таким образом, он переопределяет значение базового класса. Чтобы избежать этого поведения, вы должны просто удалить значение инициализации:

export class Filter extends Entity{
      show;
      constructor(filter?: Partial<Filter>) {
        super(filter);
        console.log('Filter', this)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...