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

JavaScript类中下划线命名的作用及移除后递归报错的疑问

JavaScript下划线命名与getter/setter常见疑问

我了解到JavaScript中的下划线是合法命名字符,本身无额外功能,仅用于标识成员为私有,但对以下代码存在疑问:

class User {
    constructor(name) {
        this.name = name
    }

    get name() {
        return this._name
    }

    set name(value) {
        if (value.length < 4) {
            alert("Name is too short")
            return
        }
        this._name = value
    }
}

let user = new User("Kiki")
alert(user.name)

疑问点:

  1. 代码中未提前定义带下划线的_name变量,JavaScript是如何识别它的?
  2. 若移除所有下划线,会触发InternalError: too much recursion错误,既然下划线无功能,为何会出现这种差异?

问题1解答

JavaScript是动态类型语言,对象的属性不需要提前声明。当执行this._name = value时,相当于直接给当前实例对象添加了一个名为_name的属性,后续访问this._name时自然就能读取到这个属性的值。简单来说,JS对象的属性是动态创建的,使用时直接赋值即可,无需提前定义。

问题2解答

这和下划线本身的功能无关,核心在于getter/setter的调用逻辑:

  • 原代码中,getter和setter操作的是_name,构造函数里的this.name = name会触发set name方法,最终把值存在_name里;读取user.name时触发get name方法返回_name,逻辑形成闭环,不会产生递归。
  • 如果移除所有下划线,getter变成return this.name,setter里的this.name = value会无限触发自身:
    1. 给this.name赋值时,会调用set name方法
    2. 方法内又执行this.name = value,再次触发set name
    3. 循环往复导致无限递归,最终抛出栈溢出错误

下划线在这里只是用来区分被getter/setter包装的对外属性名和实际存储值的内部属性名,避免调用getter/setter时产生递归冲突。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 07:36:29