为什么开发人员在JavaScript中使用get和set时会使用“ _”?

Sum*_*sal 6 javascript oop getter-setter

我知道使用下划线只是在JavaScript中定义私有变量的约定。但是我遇到了一个用例[在使用类时],其中使用_强制性似乎可以使代码正常工作!我的问题是and 被如何_使用。getset

以下代码引发错误:

RangeError:超出最大调用堆栈大小

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

  get name() {
    return this.name;
  }

  set name(val) {
    this.name = val;
  }
}

let user = new User("Jhon");
console.log(user.name);
Run Code Online (Sandbox Code Playgroud)

现在,如果我使用_代码可以正常工作!

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

  get name() {
    return this._name; // Added "_" here
  }

  set name(val) {
    this._name = val; // Added "_" here
  }
}

let user = new User("Jhon");
console.log(user.name);
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 6

您的第一个代码片段使用的getter / setter名称与您尝试分配的属性相同。因此,在构造函数中,当您执行

this.name = name;
Run Code Online (Sandbox Code Playgroud)

您正在调用name设置器,它会执行以下操作:

this.name = val;
Run Code Online (Sandbox Code Playgroud)

再次调用namesetter,该setter递归调用自身,直到堆栈溢出。

对数据的实际属性使用不同的变量名称(与getter / setter方法相比),数据可以存储在该属性中,从而使代码可以按预期工作。它不必带有下划线前缀- 除getter / setter方法使用的相同名称外,几乎所有其他方法都可以使用。

_属性名称的before通常通常表示该属性是私有的,并且只有类本身才能访问它,但这不能保证-该类的用户仍然可以随意引用user._name。如果您需要每个实例的实际私有数据,则应在带有WeakMap的闭包中定义该类,以保存私有数据:


fjc*_*fjc 4

从逻辑上看这段代码:

get name() {
    return this.name
}
Run Code Online (Sandbox Code Playgroud)

你读object.name。为了返回一个值,get name()getter 读取this.name,然后解析为get name()。现在,欢迎来到无限循环。

因此,您需要一个单独的变量名(用于存储 的实际内容name)而不是 getter 的名称。这将是一个私有变量,并且在这些情况下在前面添加下划线已成为惯例。