网站搜索

javascript - 如何在类方法中使用函数?


我有一个 calculator 类。它有以下方法:getInputFields 和 sum。

const addBtn: HTMLButtonElement = document.getElementById("add") as HTMLButtonElement;;
const subBtn: HTMLButtonElement = document.getElementById("subtract") as HTMLButtonElement;
const multiplyBtn: HTMLButtonElement = document.getElementById("multiply") as HTMLButtonElement;
const divideBtn: HTMLButtonElement = document.getElementById("divide") as HTMLButtonElement;

class Calculator {

    result: HTMLSpanElement;
    inputOne: HTMLInputElement;
    inputTwo: HTMLInputElement;
    numOne:number;
    numTwo:number;

    constructor() {
        this.result = document.getElementById("result") as HTMLSpanElement;
        this.inputOne = document.getElementById("num1") as HTMLInputElement;
        this.inputTwo = document.getElementById("num2") as HTMLInputElement;
    }

    getInputFields() {
        this.inputOne = document.getElementById("num1") as HTMLInputElement;
        this.inputTwo = document.getElementById("num2") as HTMLInputElement;
        this.numOne = parseInt(this.inputOne.value);
        this.numTwo = parseInt(this.inputTwo.value);
    }

    sum() {
        this.getInputFields();
        if (!isNaN(this.numOne) && !isNaN(this.numTwo)) {
            this.result.textContent = (this.numOne + this.numTwo).toString();
        }
    }

在上述代码的下面,我使用 addEventListener 来运行 sum 方法。

const calculator = new Calculator();
addBtn.addEventListener('click', calculator.sum);

你可以看到 this.getInputFields 在 sum() 方法里面。为什么我把它放在 sum 方法里?因为我想创建 subtract、multiplication、division 方法。但我不想在每个方法里重复相同的代码来将 document.getElementById("num1") 作为 HTMLInputElement 进行赋值。

这就是为什么我把那段代码放到 getInputFields 中。但在类方法内部这不起作用。

这是我收到的错误,

main.js:20 Uncaught TypeError: this.getInputFields is not a function
    at HTMLButtonElement.Calculator.sum (main.js:20)

答案#1

你代码中的问题在于 this 关键字的使用。在其他语言中,比如 C#,传递类方法时,它会保持与其原始组件的“关联”。在 JavaScript(以及扩展的 TypeScript)中则不是这样。

在 JavaScript 中,this 关键字是在执行时绑定的。因此,如果你调用 calculator.sum(),sum 中的 this 将绑定到 calculator,但是如果你这样做:

const func = calculator.sum;
func(); // <- inside this call, this is the global object (window)

基本上,当调用前没有 object. 时,它会隐式绑定到全局对象(在浏览器中是 window)。

在你的情况下,你可以简单地替换这一行:

addBtn.addEventListener('click', calculator.sum);

与 :

addBtn.addEventListener('click', (_clickEvent) => calculator.sum());
// or
addBtn.addEventListener('click', calculator.sum.bind(calculator));

请参考 @Thomas 在《How does the "this" keyword work?》中链接的优秀答案,以获得关于你的问题的更多示例。