ECMAScript 6 类中的 getter 和 setter 是什么?

IT技术 javascript class ecmascript-6 getter setter
2021-03-04 17:53:13

我对 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;
        }
    }
}
4个回答

这些 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

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

如果你想手动创建 setter 和 getter,这里有一个来自coryrylan.com/blog/javascript-es6-class-syntax Set的好例子set name(newName) { this._name = newName; }获取:get name() { return this._name.toUpperCase(); }
2021-04-22 17:53:13
好眼睛,@Krizzu。属性存在于 JavaScript 中,与属性完全不同。答案确实是指属性而不是属性。我已经编辑了答案。我不认为回答者会介意。:)
2021-04-29 17:53:13
如果可以,您可以在 setter 中传递多个参数吗?@大卫·拉伯格
2021-04-30 17:53:13
你的意思是财产而不是属性?对我来说有点困惑
2021-05-14 17:53:13
我不太确定这真的是一个优势,它以某种方式隐藏了使用 setter/getter 的概念。一个类的客户可能认为它直接使用了不合适的属性,但我同意它遵守信息/细节隐藏原则。也许如果我们因此使用它,它会使使用更容易,我只需要更习惯它......
2021-05-20 17:53:13

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

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

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

console.log(someEmployee.name);

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

someEmployee.name = null;

将访问 setter,并且_name由于在name's setter 中引入的保护子句,它不会修改内部属性

另请参阅一般问题为什么使用 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 属性的字段“名称”,我可以有一个不是字段的 JavaBean 属性“地址”。

JavaBean 属性也可以通过 Java 反射被数千个框架(例如 Hibernate)“发现”。因此,getter 和 setter 是“公开”bean 属性的标准方法的一部分。

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

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

      String zipcode = address.zipcode();

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

      String zipcode = address.getZipcode();

JavaScript 没有 JavaBeans 之类的东西。据我所知,GET 和 SET 的预期值仅限于前面提到的“合成”(计算)属性。

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

也就是说,如果我有:

       var zipcode = address.zipcode;

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

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

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