代码之家  ›  专栏  ›  技术社区  ›  Terry

访问扩展类中被覆盖的受保护成员

  •  0
  • Terry  · 技术社区  · 6 年前

    假设我有一个 Base a类a Test 扩展自的类 基础 。这个 基础 类有一个受保护的成员,假设它是一个存储字符串字典的对象。我想在 测验 类,但不知何故,它并没有按预期工作(至少在我的生产代码中,以及在 JS Bin ):

    type ConstantsDict = { [key: string]: string }
    
    abstract class Base {
    
        protected readonly _constants: ConstantsDict = {
            FOO: 'bar'
        }
    
        protected get _magicStringFoo(): string {
            return `Base: ${this._constants.FOO}`;
        }
    
        constructor() {
            // The magic constant FOO is incorrect when invoked in Test
            alert(this._magicStringFoo);
        }
    }
    
    class Test extends Base {
        // Overwrite inherited  member
        protected readonly _constants = {
            FOO: 'lorem ipsum dolor sit amet'
        }
    
        // Overwrite inherited getter
        protected get _magicStringFoo(): string {
            return `Test: ${this._constants.FOO}`;
        }
    
        // Let's give Test it's own getter for the same magic constant
        private get _magicStringFooPrivate(): string {
            return `Test: ${this._constants.FOO}`;
        }
    
        constructor() {
            super();
    
            // The magic constant FOO is correct over here
            alert(`Local magic constant FOO is: ${this._magicStringFooPrivate}`)
        }
    }
    
    new Test();
    

    代码将发出警报 Test: bar 而不是 Test: lorem ipsum dolor sit amet 。好消息是受保护的getter继承自 基础 类正在中被覆盖 测验 ,但不知何故 this 引用仍然指向不正确的类。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Fenton    6 年前

    这是由构造函数如何交互引起的排序问题。

    以下是基于代码的构造函数(为了便于使用,删除了所有其他代码)。

    我已经在每一行上注释了当您实例化一个新的 Test

    // 3
    function Base() { 
        // 4
        this._constants = { 
            // 5
            FOO: 'bar' 
        // 6
        }; 
        // 7 (at this point, FOO is 'bar')
        alert(this._magicStringFoo);
    }
    
    // 1
    function Test() { 
        // 2
        var _this = _super.call(this) || this; // <-- GO TO SUPER CLASS CONSTRUCTOR
        // 8
        _this._constants = {
            // 9
            FOO: 'lorem ipsum dolor sit amet'
        // 10
        };
        // 11
        alert("Local magic constant FOO is: " + _this._magicStringFooPrivate);
        //12
        return _this;
    }
    

    您可以在这里看到为什么子类似乎具有错误的值-它只是没有机会在此时覆盖基类值。

    修理

    我建议的修复方法是将值传递给超类构造函数。

    以下是一个简单的版本:

    type ConstantsDict = { [key: string]: string }
    
    abstract class Base {
        constructor(protected magicStringFoo: string) {
            // The magic constant FOO is incorrect when invoked in Test
            alert(this.magicStringFoo);
        }
    }
    
    class Test extends Base {
        constructor() {
            super('Test: lorem ipsum dolor sit amet');
        }
    }
    
    new Test();
    

    我已经通过了那里的测试字符串,但您可以通过 FOO 常量或您需要的任何内容。这解决了任何订购问题。