模块模式中 get/set 和 Object.defineProperty 的区别

Difference between get/set and Object.defineProperty in the Module Pattern

我见过在模块模式中实现 getters/setters 的两种不同方式。一个使用 "defineProperty",而另一个不使用。两者的 advantages/disadvantages 是多少?

var MyModule = (function() {

  var _val;

  var api = {
    get value1() {
      return _val
    },
    set value1(value) {
      _val = value
    }
  };

  Object.defineProperty(api, 'value2', {
    get: function() {
      return _val;
    },
    set: function(value) {
      _val = value
    }
  });
  return api;

}());

https://plnkr.co/edit/TbJSD4noZTew8II83eTH?p=preview

使用 getter syntax 创建一个 属性,在 ES2015 之前,您必须在编写代码时知道其名称。

Object.defineProperty 允许您执行与上述相同的操作,但即使在 ES2015 之前,也不需要您提前知道 属性 的名称。它还允许您决定 属性 是可配置的、可枚举的还是可写的,而使用 get/set 语法是不可能的。

回答你的确切问题:两者都不是更好。它们适用于不同的情况。 get/set 语法更易于读写,但不如 Object.defineProperty.

强大

Object.defineProperty 与 get/set 符号中的一个 "advantage" 是 defineProperty 可以在任何时候使用,即使是在已经创建的对象上(你不能在其上使用 shorthand 'get' 符号)。来自 mdn:

To append a getter to an existing object later at any time, use Object.defineProperty().

如文档中所述。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

正常的 属性 通过赋值添加会创建在 属性 枚举期间显示的属性(for...in 循环或 Object.keys 方法),其值可能会更改,并且可能会被删除。此方法允许更改这些额外详细信息的默认值。默认情况下,使用 Object.defineProperty() 添加的值是不可变的。