在 ECMAScript 6 类中,getter 和 setter 有什么用

What are getters and setters for in ECMAScript 6 classes?

本文关键字:setter 什么 getter ECMAScript 类中      更新时间:2023-09-26

我对 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;
        }
    }
}

这些 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 中的 Getter 和 setter 与其他语言的目的相同......包括ES5。ES5已经允许吸气手和二传手通过Object.defineProperty,尽管它们不那么干净,使用起来更麻烦。

实际上,getter 和 setter 允许您使用标准属性访问表示法进行读取和写入,同时仍然能够自定义属性的检索和更改方式,而无需显式的 getter 和 setter 方法。

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

console.log(someEmployee.name);

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

someEmployee.name = null;

将访问 setter,并且它不会因为 name 的 setter 中引入的 guard 子句而修改内部 _name 属性。

另请参阅一般问题 为什么使用 getter 和 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就像间谍一样。它窥探对象的属性,以便每次获取或设置属性的值时都可以执行某些操作。

ES6 getter 和 setter 的动机与 Java 中的类似概念大不相同。

在Java中,getter和setter允许类定义JavaBean。 getter 和 setter 的要点是,它允许 bean 具有与公共字段所暗示的完全正交的"接口"。 所以我可以有一个不是JavaBean属性的字段"name",我可以有一个不是字段的JavaBean属性"地址"。

JavaBean属性也可以通过Java反射被成千上万的框架(例如Hibernate)"发现"。 因此,吸啦剂和二传手是"暴露"豆属性的标准方法的一部分。

作为函数,Getter 和 setter 也具有它们"抽象"实现的价值。 它可以是字段或计算("合成")值。 因此,如果我有一个名为"zipcode"的 bean 属性,它以存储的字符串开始。 现在假设我想将其更改为从地址/城市/州计算的值?

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

      String zipcode = address.zipcode();

但是如果我使用吸气剂,这不会中断:

      String zipcode = address.getZipcode();

JavaScript没有像JavaBeans那样的东西。 据我所知,GET和SET的预期值仅限于上述"合成"(计算)属性。

但它比Java好一些,因为虽然Java不允许你将"字段"兼容地转换为方法,但ES6 GET和SET允许这样做。

也就是说,如果我有:

       var zipcode = address.zipcode;

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

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

所以我认为这些是理解Java和JavaScript ES6getters和setters之间的一些重要区别。