JS:类 getter/setter 与直接更改属性

时间:2021-02-02 03:44:54

标签: javascript

class Person {
  constructor(name) {
    this._name = name;
  }

  get name() {
    return this._name.toUpperCase();
  }

  set name(newName) {
    this._name = newName; 
  }
}

let newPerson  = new Person("mike") 

getter 和 setter 有什么好处?我还不能通过 newPerson._name 获得它并获得 mike 吗?要设置它,我不能只执行 newPerson._name = "Phil" 来设置它吗?

2 个答案:

答案 0 :(得分:2)

查看 getter 应该会给你一个提示:

  get name() {
    return this._name.toUpperCase();
  }

它可以让您执行可能很复杂的逻辑,伪装成简单的属性查找。再举一个例子,考虑如果你有 firstNamelastName 属性 - 那么你可以让 name 成为实际基础属性的 getter/setter:

class Person {
  constructor(name) {
    // Invoke the setter below
    this.name = name;
  }

  get name() {
    return this._firstName + ' ' + this._lastName;
  }

  set name(newName) {
    const [first, last] = newName.split(' ');
    this._firstName = first;
    this._lastName = last;
  }
}

let newPerson  = new Person("John Smith") 
console.log(newPerson.name);

如果没有 getter/setter,这种功能(运行逻辑并返回自定义的东西而不是只返回普通的属性值)是不可能的。

也就是说,对于您的原始代码,除了 toUpperCase 部分,是的,getter/setter 并没有真正为您做很多事情。

<块引用>

我不能只做 newPerson._name = "Phil" 来设置它吗?

是的,你可以。下划线通常用于表示一个属性不应该在类的外部使用,但它们不会完全禁止。如果您想让属性真正私有,请使用 # 私有字段语法。

class Person {
  #firstName;
  #lastName;
  constructor(name) {
    // Invoke the setter below
    this.name = name;
  }

  get name() {
    return this.#firstName + ' ' + this.#lastName;
  }

  set name(newName) {
    const [first, last] = newName.split(' ');
    this.#firstName = first;
    this.#lastName = last;
  }
}

let newPerson  = new Person("John Smith") 
console.log(newPerson.name);

答案 1 :(得分:0)

封装有一些好处,包括验证数据(如果设置错误的值会抛出错误)和适当地格式化(返回“用户没有名字”而不是 undefined)。这也意味着如果您决定更改对象数据的处理方式,您可以将 getter/setter 指向新数据,而不必不断更新过时的属性。如果您更喜欢属性的语法,JavaScript 有 Proxy 对象来实现这些 getter/setter 功能。

关于封装的这个 article 可能有用。