【问题标题】:How to use a callback function in a class with inheritance如何在具有继承的类中使用回调函数
【发布时间】:2022-01-07 18:24:23
【问题描述】:

如何在用作回调函数的子方法中使用父方法中的方法

class Parent {
    numbers: number[];

    constructor(numbers: number[]) {
        this.numbers = numbers;
    }

    protected iterateNumbers(iterCallback: (nb: number) => void): void {
        for (const nb of this.numbers) {
            iterCallback(nb);
        }
    }

    protected inc(nb: number): number {
        return nb++;
    }
}

class Child extends Parent {
    constructor(numbers: number[]) {
        super(numbers)
    }

    getNumbers(): void {
        this.iterateNumbers(this.displayNumber);
    }

    private displayNumber(nb: number): void {
        console.log(this.inc(nb));
    }
}

const c = new Child([1, 2, 3, 4, 5]);
c.getNumbers();

此代码导致此错误:TypeError: Cannot read property 'inc' of undefined

用 super() 修改

【问题讨论】:

    标签: javascript typescript oop callback


    【解决方案1】:

    您需要在子类的构造函数中调用父类的方法才能访问父类的属性和方法。

    此外,由于您拥有 displayNumber 私有方法,因此您将无法从 child 类创建的对象中访问它。删除 private 关键字将允许访问

    尝试更改您的扩展子项以包含构造函数方法和超级调用:

    class Child extends Parent {
    
        constructor() {
            super()
        }
        
        getNumbers(): void {
            this.iterateNumbers(this.displayNumber);
        }
    
        displayNumber(nb: number): void {
            console.log(this.inc(nb));
        }
    }
    

    您可以在MDN docs on the super keyword阅读更多内容

    更新:

    经过一些测试后,我找到了解决您为什么会收到该错误的方法,当然这完全与上下文有关。如果您将inc 方法设为静态,您将能够通过Parent.inc() 调用它

    通过将displayNumber 方法作为回调传入,您将失去要从中调用它的类的上下文。这就是您收到未定义错误的原因。

    class Parent {
        numbers: number[];
    
        constructor(numbers: number[]) {
            this.numbers = numbers;
        }
    
        protected iterateNumbers(iterCallback: (nb: number) => void): void {
            for (const nb of this.numbers) {
                iterCallback(nb);
            }
        }
    
        static inc(nb: number): number {
            return nb++;
        }
    }
    
    class Child extends Parent {
        constructor(numbers: number[]) {
            super(numbers)
        }
    
        getNumbers(): void {
            this.iterateNumbers(this.displayNumber);
        }
    
        private displayNumber(nb: number): void {
            console.log(Parent.inc(nb));
        }
    }
    
    const c = new Child([1, 2, 3, 4, 5]);
    c.getNumbers(); // prints 1 2 3 4 5
    

    如果您运行此代码,您将看到打印出来的数字。

    现在通过在child构造函数中调用super方法和将inc方法更新为静态,并这样调用它,我想你会得到预期的结果。

    【讨论】:

    • 我已经修改了代码,但它仍然不起作用我第一次能够在 getNumbers() 中访问 this.iterateNumbers() 但不能在 displayNumber() 方法中访问
    • 我已经更新了我的答案,因为它是私人的,你将无法访问它
    • 受保护不是问题
    • 对不起,我写错了。我相信这是因为您将 displayNumber 设为私有。尝试不使用 private 关键字
    • 我已经更新了我的答案,包括使用 static 关键字以及为什么你得到未定义
    【解决方案2】:

    找到了一种方法来做同样的事情,但使用非静态方法

    ES6 风格允许你使用新的特性,比如 super 关键字。 super 关键字都是关于父类上下文的,当你使用 ES6 类语法时。

    class Parent {
        numbers: number[];
    
        constructor(numbers: number[]) {
            this.numbers = numbers;
        }
    
        protected iterateNumbers(predictionCallback: (nb: number) => void): void {
            for (const nb of this.numbers) {
                predictionCallback(nb);
            }
        }
    
        protected inc(nb: number): number {
            return nb++;
        }
    }
    
    class Child extends Parent {
    
        constructor(numbers: number[]) {
            super(numbers)
        }
    
        getNumbers() {
            this.iterateNumbers(this.displayNumber);
        }
    
        private displayNumber(nb: number): void {
            console.log(super.inc(nb));
        }
    }
    
    const c = new Child([1, 2, 3, 4, 5]);
    c.getNumbers();
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      • 2020-01-23
      • 2014-11-27
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      相关资源
      最近更新 更多