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)
疑问点:
- 代码中未提前定义带下划线的
_name变量,JavaScript是如何识别它的? - 若移除所有下划线,会触发
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会无限触发自身:- 给
this.name赋值时,会调用set name方法 - 方法内又执行
this.name = value,再次触发set name - 循环往复导致无限递归,最终抛出栈溢出错误
- 给
下划线在这里只是用来区分被getter/setter包装的对外属性名和实际存储值的内部属性名,避免调用getter/setter时产生递归冲突。
内容的提问来源于stack exchange,提问作者sljafna
相关产品推荐
相关产品推荐

