浅谈 JS 对象属性描述符(property descriptor)对象

248 阅读1分钟

属性描述符(property descriptor)对象

  • value:就是属性的值,默认 undefined
  • writable:决定属性能否被赋值
  • get:访问器函数(getter),函数或 undefined,在取属性值时被调用
  • set:设置器函数(setter),函数或 undefined,在设置属性值时被调用
  • enumerable:决定 for in 或 Object.keys 能否枚举该属性
  • configurable:决定该属性能否被删除,以及除 value 和 writable 外的其他特性是否可以被修改

数据描述符

value, writable, enumerable, configurable

存取描述符

get, set, enumerable, configurable

如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。
如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。

相关方法

Object.defineProperty(obj, prop, descriptor)

Object.defineProperties(obj, props)

Object.getOwnPropertyDescripter(obj, prop)

Object.getOwnPropertyDescripters(obj)

let obj2 = {
	_name: 'zty',
	get name() {
		return this._name
	},
	set name(name) {
		this._name = name + '1'
	}
}

obj2.name  // "zty"
obj2.name = 'zzx'
obj2.name  // "zzx1"

Object.getOwnPropertyDescriptor(obj2, 'name')
{
    configurable: true,
    enumerable: true,
    get: ƒ name(),
    set: ƒ name(name)
}
Object.getOwnPropertyDescriptor(obj2, '_name')
{
    configurable: true,
    enumerable: true,
    value: "zzx1",
    writable: true
}
Object.getOwnPropertyDescriptors(obj2)
{
    name: {
        configurable: true,
        enumerable: true,
        get: ƒ name(),
        set: ƒ name(name)
    },
    _name: {
        configurable: true,
        enumerable: true,
        value: "zzx1",
        writable: true
    }
}
如果对象属性由 Object.defineProperty(obj, 'key', descriptor) 定义,则 writable, enumerable, configurable 默认均为 false
如果对象属性由 obj.key = 'value' 定义,则 writable, enumerable, configurable 均为 true
let obj = {}
obj.key1 = 'value1'
let descriptor = Object.create(null)
descriptor.value = 'value2'
Object.defineProperty(obj, 'key2', descriptor)
Object.getOwnPropertyDescriptors(obj)
{
    key1: {value: "value1", writable: true, enumerable: true, configurable: true},
    key2: {value: "value2", writable: false, enumerable: false, configurable: false}
}

// 也就是说
o.a = 1;
// 等同于 :
Object.defineProperty(o, "a", {
  value : 1,
  writable : true,
  configurable : true,
  enumerable : true
});

// 另一方面,
Object.defineProperty(o, "a", { value : 1 });
// 等同于 :
Object.defineProperty(o, "a", {
  value : 1,
  writable : false,
  configurable : false,
  enumerable : false
});