前言
Object.defineProperty()是直接在一个对象上定义一个新的属性,或者是修改已存在的属性。最终这个方法会返回该对象。简单来说就是为对象定义属性。那么在我们使用 Object.defineProperty()之前,我们是如何给对象添加或者修改属性的,下面看代码
var obj = {}
obj.name = '张三'
obj['age'] = 18
console.log(obj) // {name: "张三", age: 18}
我们可以很简单的就为对象添加或者修改一个属性,那为啥还需要Object.defineProperty()呢?那是因为Object.defineProperty()可以更深层次的定义属性,下面详细介绍。
参数
Object.defineProperty(obj, prop, descriptor)
obj:必须:要在其上添加或修改属性的对象
prop:必须:一个包含属性名称的字符串
descriptor 必需。 属性描述符。 包含6个属性:configurable、enumerable、writable、value、get、set
obj和prop很好理解,我们详细说一下descriptor参数吧:
configurable
configurable如果为false,那么除了value和writable之外的特性都不能被修改(包括自身),并且writable为true可修改为false,如果writable为false,修改为true也会被忽略
var obj = {
name: '张三',
}
Object.defineProperty(obj,'name',{
configurable: false
})
console.log(obj) // {name: "张三"}
// 修改value值
Object.defineProperty(obj,'name',{
value: '李四',
})
console.log(obj) // {name: "李四"}
// 修改writable为false
Object.defineProperty(obj,'name',{
writable: false
})
obj.name = '王五'
console.log(obj) // {name: "李四"}
enumerable
enumerable为true代表可枚举,为false为不可枚举,默认值是true。for in可以遍历出可枚举的属性。
var obj = {
name:'张三'
}
// 把age的enumerable属性设为false代表不可枚举,这个时候for in是遍历不出来这个属性的
Object.defineProperty(obj,'age',{
value: 18,
enumerable: false
})
for (const key in obj) {
console.log(key) // name
}
// enumerable为true的情况
Object.defineProperty(obj,'address',{
value: '上海',
enumerable: true
})
for (const key in obj) {
console.log(key) // name,address
}
writable
writable为true的时候可以改变属性的value值,如果writable为false的时候修改value值无效
var obj = {
name:'张三'
}
// 把age的enumerable属性设为false代表不可枚举,这个时候for in是遍历不出来这个属性的
Object.defineProperty(obj,'age',{
value: 18,
writable: true
})
obj.age = 99
console.log(obj) // {name: "张三", age: 99}
// 将writable设置为false
Object.defineProperty(obj,'age',{
writable: false
})
obj.age = 100
console.log(obj) // {name: "张三", age: 99} 这个时候修改age会失效
value
value就是某个属性的值
var obj = {}
// value代表将name的属性值设置为赵六
Object.defineProperty(obj,'name',{
value: '赵六'
})
console.log(obj) // {name: "赵六"}
get
在读取属性时调用的函数。默认值是undefined
var obj = {}
Object.defineProperty(obj, 'name', {
get: function() {
return '张三'
}
})
console.log(obj.name) // 张三
set
在写入属性时调用的函数。默认是undefined
var obj = {}
var name = '张三'
Object.defineProperty(obj, 'name', {
get: function () {
return name
},
set: function(newVal) {
(name !== newVal) && (name = newVal)
}
})
console.log(obj.name) // 张三
obj.name = '李四'
console.log(obj.name) // 李四
console.log(name) // 李四
// 啊这,不就是双向数据绑定的原理吗