Object.defineProperty()在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
句法
Object.defineProperty(obj, prop, descriptor)
obj
:目标对象
prop
:要操作对象的属性
descriptor
:属性的配置信息对象。
descriptor
descriptor是一个对象,有以下配置项。
value
:该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)
writable
:当且仅当该属性的 writable 键值为 true时,属性的值,也就是上面的value,才能被赋值运算符改变。默认为 false
enumerable
:当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。默认为 false
configurable
:当且仅当该属性的 configurable 键值为 true 时,该属性的descriptor才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false
let rose = {age: 18}
Object.defineProperty(rose, 'gender', {
value: 'female',
// writable:false,
// enumerable:false,
// configurable:false
})
rose.gender='male'
console.log(rose)//gender依旧为female,因为writable默认为false
console.log(Object.keys(rose))//只有age一个项,因为enumerable默认为false
console.log(delete rose.gender) //false 删除失败,configurable默认为false
Object.defineProperty(rose, 'gender', {
value: 'male',
writable:true
})// Uncaught TypeError: Cannot redefine property: gender at Function.defineProperty configurable默认为false,配置项不能修改,在第一次定义为true时就可以修改
get
用来读取属性值的函数
set
用来设置属性值的函数
!!注意:【value/writable】和【get/set】不能同时存在。
const o = {}
let bValue = 38;
Object.defineProperty(o, "b", {
get() {
return bValue;
},
set(newValue) {
bValue = newValue;
},
enumerable: true,
configurable: true,
});
get和set可以用来做响应式数据的监测,Vue2的响应式就是基于此实现的。
let data = {
name: 'zyl',
hobby: ['diving', 'basketball'],
age: 18
}
function Observer(obj) {
let keys = Object.keys(obj)
keys.forEach((key) => {
Object.defineProperty(this, key, {
get() {
return obj[key]
},
set(val) {
console.log(`${key}属性改变了,执行更新模板操作`)
obj[key] = val
}
})
})
}
let vm = {}
vm._data= data = new Observer(data)
data.age = 20
// console.log(vm._data)
function set(obj, key, val) {
let _val = val
Object.defineProperty(obj, key, {
get() {
return _val
},
set(value) {
_val = value
}
})
}
set(vm._data, 'favoriteColor', 'green')