You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript类已定义属性仍报TypeError的解决方法

问题描述

我编写了一个代表HTML元素的JavaScript类,用于答题程序,包含用户输入答案的文本框、提交判分的按钮,以及显示正误状态的文本。类的构造函数如下:

constructor(correctAnswer) {
    this.correctAnswer = correctAnswer;
    
    this.rootHTMLElement = document.createElement("div");

    this.textInputElement = document.createElement("input");
    this.textInputElement.type = "text";
    this.rootHTMLElement.appendChild(this.textInputElement);

    this.statusIndicatorElement = document.createElement("span");
    this.rootHTMLElement.appendChild(this.statusIndicatorElement);

    this.button = document.createElement("button");
    this.button.innerText = "Mark";
    this.rootHTMLElement.appendChild(this.button);
    this.button.addEventListener("click", this.markSelf);
}

按钮事件监听调用的markSelf方法如下:

markSelf() {        
    switch (this.textInputElement.value) {
        case this.correctAnswer:
            this.statusIndicatorElement.innerText = "Correct";
            break
        case "":
            this.statusIndicatorElement.innerText = "Not marked";
            break
        default:
            this.statusIndicatorElement.innerText = "Incorrect";
            break
    }
}

仅构造函数和markSelf方法访问this.textInputElement,但点击按钮时却抛出错误:Uncaught TypeError: this.textInputElement is undefined。请问如何修改代码,实现根据输入内容判断答案正误并更新statusIndicatorElement内容的功能?

问题原因

事件处理函数执行时,this的指向是触发事件的DOM元素(即点击的按钮),而非类的实例对象。因此在markSelf中访问this.textInputElement时,实际上是在按钮元素上查找该属性,自然会返回undefined。

解决方案

以下三种方法均可解决this指向问题,任选其一即可:

方法1:在构造函数中绑定this

修改构造函数中的事件监听代码,使用bind()将markSelf的this绑定为类实例:

constructor(correctAnswer) {
    // ... 原有代码不变 ...
    this.button.addEventListener("click", this.markSelf.bind(this));
}

bind()会返回一个新函数,其内部this固定为传入的类实例,这样点击按钮时执行的markSelf就能正确访问类的属性。

方法2:使用箭头函数作为事件回调

箭头函数的this继承自外层作用域(此处为构造函数的this,即类实例),因此可以直接用箭头函数包裹markSelf调用:

constructor(correctAnswer) {
    // ... 原有代码不变 ...
    this.button.addEventListener("click", () => this.markSelf());
}

点击按钮时,箭头函数会调用this.markSelf(),此时的this就是类实例。

方法3:将markSelf定义为类箭头函数方法

直接把markSelf定义为类的箭头函数属性,这样它的this会始终绑定类实例:

markSelf = () => {        
    switch (this.textInputElement.value) {
        case this.correctAnswer:
            this.statusIndicatorElement.innerText = "Correct";
            break
        case "":
            this.statusIndicatorElement.innerText = "Not marked";
            break
        default:
            this.statusIndicatorElement.innerText = "Incorrect";
            break
    }
}

这种方式下,构造函数中的事件监听代码无需修改,this.markSelf的this已经固定为类实例。

内容的提问来源于stack exchange,提问作者pythonmegapixel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:20:25