ECMAScript 6 类 中的 getter 和 setter 有什么用?

What are getters and setters for in ECMAScript 6 classes?

我对 ECMAScript 6 中 getter 和 setter 的意义感到困惑 类。什么目的?以下是我所指的示例:

class Employee {

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

    doWork() {
        return `${this._name} is working`;
    }

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

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

ES6 中的 Getters 和 setters 与它们在其他语言中的作用相同......包括 ES5。 ES5 已经通过 Object.defineProperty 允许 getters 和 setters,尽管它们不太干净且使用起来更麻烦。

实际上,getters 和 setters 允许您使用标准的 属性 访问符号进行读写,同时仍然能够自定义 属性无需显式 getter 和 setter 方法即可检索和变异。

在上面的 Employee class 中,这意味着您可以像这样访问 name 属性:

console.log(someEmployee.name);

看起来 像正常的 属性 访问,但它实际上会在返回名称之前调用 toUpperCase 。同样,这样做:

someEmployee.name = null;

会访问 setter,并且不会修改内部 _name 属性,因为 name 的 setter 中引入了保护子句.

另请参阅一般性问题 Why use getters and setters?,了解有关为什么能够修改成员访问功能很有用的更多信息。

这些 setter 和 getter 允许您直接使用属性(不使用括号)

var emp = new Employee("TruMan1");

if (emp.name) { 
  // uses the get method in the background
}

emp.name = "New name"; // uses the setter in the background

这里只是设置和获取属性的值。

ES6 getters 和 setter 与 Java.

中的类似概念有着截然不同的动机

在Java中,getters和setter允许class定义一个JavaBean。 getters 和 setter 的要点在于它允许 bean 具有与 public 字段隐含的完全正交的 "interface"。所以我可以有一个字段 "name" 不是 JavaBean 属性,我可以有一个 JavaBean 属性 "address"不是一个字段。

JavaBean 属性也被成千上万的框架(例如 Hibernate)通过 Java 反射 "discoverable"。因此,getters 和 setter 是 "exposing" bean 属性的标准方法的一部分。

Getter 和 setter 作为函数,也具有它们 "abstract" 实现的价值。它可以是字段或计算的 ("synthetic") 值。因此,如果我有一个名为 "zipcode" 的 bean 属性,它开始时是存储的字符串。现在假设我想将其更改为根据 address/city/state?

计算的值

如果我使用字段,此代码会中断:

      String zipcode = address.zipcode();

但是如果我使用 getter,这不会中断:

      String zipcode = address.getZipcode();

Java脚本没有 JavaBeans 之类的东西。据我所知,GET 和 SET 的预期值仅限于上述 "synthetic"(计算)属性。

但它比 java 稍微好一点,虽然 Java 不允许您将 "field" 兼容地转换为方法,但 ES6 GET 和 SET 允许这样做。

也就是说,如果我有:

       var zipcode = address.zipcode;

如果我将邮政编码从标准对象 属性 更改为 getter,上面的代码现在调用 GET 函数。

请注意,如果我没有在定义中包含 GET,这将不会调用邮政编码 GET 方法。相反,它只会将函数 zipcode 分配给 var.

所以我认为这些是 Java 和 JavaScript ES6 getters 和 setter 之间需要理解的一些重要区别。

class Employee {

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

    doWork() {
      return `${this._name} is working`;
    }

    get name() {
      // when you get this by employeeInstance.name
      // the code below will be triggered
      // and you can do some logic here
      // just like `console.log` something you want
      console.log('get triggered!')
      return this._name.toUpperCase();
    }

    set name(newName) {
      // the same as `get`
      // when you employeeInstance.mame = 'xxx'
      // the code below will be trigged
      // and you can also do some logic 
      // like here is a `console.log` and `if check`
      console.log('set triggered!')
      if (newName) {
        this._name = newName;
      }
    }
  }

  const employeeInstance = new Employee('mike')
  employeeInstance.name
  employeeInstance.name = '' // this won't be successful, because the `if check`
  console.log(employeeInstance.name)

  // => 
  // get triggered
  // set triggered
  // get triggered
  // MIKE

反正gettersetter就是个间谍。它会侦测对象的 属性,以便您可以在每次获取或设置 属性.

的值时执行某些操作