Object.defineproperty(obj, prop, descriptor) 可以添加/修改对象的属性,调用后会返回该对象。和平时直接添加对象属性:var obj = {title: ''} 是有区别的。通过 Object.defineproperty 定义可以配置对象属性是否可以枚举/删除/可写以及为属性添加自定义的 getter/setter 等特性。
var obj = {}
Object.defineProperty(obj, 'a', {
// 属性描述符是否可改变和属性是否可删除,默认 false,防止通过 defineProperty 重新定义属性的值,所以要设置为 false
configurable: false,
// 是否可写,默认 false
writable: false,
// 值
value: 0
})
// 修改无效,因为属性描述为不可写
obj.a = 10
// 修改无效,因为属性 a 的 configurable 为 false
Object.defineProperty(obj, 'a', { value: 10 })
consolg.log(obj.a) // 还是 0
var obj = {}
Object.defineProperty(obj, 'a', {
configurable: false,
value: 0
})
// 删除无效,因为属性 a 的 configurable 为 false
delete obj.a // false
consolg.log(obj.a) // 还是 0
var obj = {}
Object.defineProperty(obj, 'a', {
// 是否可枚举,默认 false
enumerable: false,
// 值
value: 0
})
Object.keys(obj) // []
for (prop in obj) {} // 没有属性
var obj = {}
var value = 10
// 数据描述符和属性描述符 writable 不能同时存在,否则报错
Object.defineProperty(obj, "a", {
get: function(){
return value
},
set: function(newValue){
value = newValue
}
})
obj.a = 20
实现一个修改对象属性自动更新页面 UI 的小效果
<input id="J_textInput" type="text" onkeyup="change(this.value)" />
<p id="J_text"></p>
<script>
var input = {}
Object.defineProperty(input, 'value', {
// 当修改 value 时,执行 render 函数重新渲染
set: function(newValue){
render(newValue)
}
})
function change(value) {
input.value = value
}
function render(value){
document.getElementById('J_textInput').value = value
document.getElementById('J_text').innerText = value
}
input.value = 'test'
</script>