Object.defineProperty实践
概述
Object.defineProperty() 用于在对象上定义新属性或修改现有属性,并返回修改后的对象;之所以使用 defineProperty() ,是因为它能精确的控制属性。
Object.defineProperty() 方法有三个参数,参数一是欲新增或修改属性的对象,参数二是属性名称,参数三是属性描述符;属性的描述符用于声明属性的其它特性,如:属性值、属性是否可读写、属性是否可再配置、属性是否可删除、属性的Get/Set方法等;
普通属性的定义和赋值
let Person = {}
Person.name = 'Jack'
Person['gender'] = 'female'
使用Object.defineProperty()进行属性的定义和赋值
// 1.添加属性
let obj = {};
Object.defineProperty(obj, 'name', {value:'steve'});
obj.name; // 'steve'
// 2.修改现有属性,重返18岁
obj.age = 27;
Object.defineProperty(obj, 'age', {value:18});
obj.age; // 18
属性的特性
JS中有三种属性:
- 数据属性:拥有确定值的普通属性;
- 访问器属性:通过
getter
和setter
进行读取和赋值的属性; - 内部属性:由 JS 引擎内部使用的属性,外部不能直接访问,但可通过一些方法间接读取和设置,如:
[[Scopes]]
。
每个对象都有一个内部属性[[Prototype]]
,代码中不能直接访问,但可通过 Object.getPrototypeOf()
间接读取。
属性描述符(descriptor)
属性描述符有两种,分别为数据描述符和存取描述符,两者不可同时使用,如下详解:
1>. 存取描述符:(getter、setter)
let Person = {}
let temp = null
Object.defineProperty(Person, 'name', {
get: function () { // 为属性添加 getter 方法
return temp
},
set: function (val) { // 为属性添加 setter 方法
temp = val
}
})
temp = 'steve'
console.log(Person.name) // steve
2>. 数据描述符和存取描述均具有以下描述符:(value、configurable、enumerable、writable)
let Person = {}
Object.defineProperty(Person, 'name', {
value: 'jobs', // 属性值
configurable:false, // 设置属性可否再配置、可否删除
enumerable:false, // 设置该属性的 key 是否可以被 for in 或者 Object.keys() 遍历
writable: true, // 是否可写(该属性值是否可改变,如果不设置,默认为 false,不可改变)
})
delete Person.name // false
// 重新修改 Person 类的 class 属性配置,报错,Cannot redefine property!
Object.defineProperty(Person, 'name', {
value: 2,
})
当一个属性的 configurable 被设置为 false 之后,则不能重新定义这个属性,也不能删除这个属性。
当configurable
为false
时,可以把writable
的状态由true
改为false
,但是无法由false
改为true
。当configurable
为true
时,writable
的状态可以随意更改。
默认值
如果属性描述符中某些配置被省略,则默认配置如下:
let Person = {}
Object.defineProperty(Person, 'name', {})
// 等价于
Object.defineProperty(Person, 'name', {
value: undefined,
writable: false,
enumerable:false,
configurable:false,
get:undefined,
set:undefined
})
普通属性普通
let Person = {}
Person.name = 'steve'
// 等价于
Object.defineProperty(Person, 'name', {
value: 'steve',
writable: true,
enumerable:true,
configurable:true
})
详见MDN
其它:https://cloud.tencent.com/developer/article/1769810