数据属性和访问器属性相关总结 - pod4g/tool GitHub Wiki

一、数据属性

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有 4 个描述其行为的 特性。

  • Configurable: 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
  • Enumerable: 表示能否通过for-in循环返回属性。
  • Writable: 表示能否修改属性的值。
  • Value: 包含这个属性的数据值。

默认即为数据属性,其[Configurable](/pod4g/tool/wiki/Configurable)[Enumerable](/pod4g/tool/wiki/Enumerable)[Writable](/pod4g/tool/wiki/Writable)的值为 true

二、访问器属性

访问器属性不包含数据值;它们包含一对儿getter和setter 函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调用getter 函数,这个函数负责返回有效的值;在写入访问器属性时,会调用 setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性有如下 4 个特性。

  • Configurable:特性同1.1数据属性的该特征值
  • Enumerable:特性同1.1数据属性的该特征值
  • Get:在读取属性时调用的函数。默认值为 undefined。
  • Set:在写入属性时调用的函数。默认值为 undefined。

访问器属性不能直接定义,必须使用 Object.defineProperty()来定义。


2020-06-09补充,上面的说法是错误的,实际上,我们可以用get 语法来定义访问器属性

例如

var p = {
  get name() {
    return 'liyanfeng'
  }
}
Object.getOwnPropertyDescriptor(p, 'name') // {set: undefined, enumerable: true, configurable: true, get: ƒ}


var p2 = {}
Object.defineProperty(p2, 'name', {get() { return '123' }})
Object.getOwnPropertyDescriptor(p2, 'name') // {set: undefined, enumerable: false, configurable: false, get: ƒ}

三、descriptor的默认值

2020-06-15补充

上面说过,我们定义一个属性,默认是数据属性,除value以外,其他值都是true

例如

window.prop = true

Object.getOwnPropertyDescriptor(window, 'prop') // {value: true, writable: true, enumerable: true, configurable: true}

今天看webpack打包以后的源码,发现这种用法:

Object.defineProperty(exports, name, { enumerable: true, get: getter });
Object.defineProperty(exports, '__esModule', { value: true });

这种只指定一部分descriptor的值,那么其他的值是什么?

验证:

Object.defineProperty(window, '__esModule', { value: true });
Object.getOwnPropertyDescriptor(window, '__esModule') // {value: true, writable: false, enumerable: false, configurable: false}

Object.defineProperty(window, '__jsModule', { enumerable: true, get: getter }) // {set: undefined, enumerable: true, configurable: false, get: ƒ}

得出结论:如果使用defineProperty定义属性,没有指定的boolean值都为false,非boolean值为undefined