详解 Object.defineProperty() & Object.defineProperties()
·
Object.defineProperty()
- 该方法用于在一个对象上定义一个新属性,或者修改一个对象上已有的属性,并返回修改后的原对象
Object.defineProperty(obj, prop, descriptor)
- 该方法需要传递三个参数:
- obj:需要定义新属性或修改属性的对象
- prop:一个字符串或 Symbol,指明要定义新属性或修改属性的 key
- descriptor:对定义的新属性或修改的属性的描述符,描述指定的属性是否可以修改、是否可以删除等
- 该方法返回传入的对象,该对象指定的属性已被新增或修改
描述指定属性的值 value
<script>
let person = {
name: 'zs',
sex: 'male'
}
// 向 person 对象中新添加一个 age 属性
// 同时指定新添加的属性值为 18
Object.defineProperty(person, 'age', {
value: 18
})
console.log(person)
</script>
描述指定属性是否可枚举 enumerable
- 使用 Object.defineProperty() 添加的属性默认是不可枚举,即使用 Object.defineProperty() 添加的属性默认是不能进行遍历的。
<script>
let person = {
name: 'zs',
sex: 'male'
}
// 向person对象中新添加一个age属性
Object.defineProperty(person, 'age', {
value: 18
})
console.log(person)
console.log(Object.keys(person))
for (let key in person) {
console.log(key, person[key])
}
</script>

- 在使用 Object.defineProperty() 添加属性的时候,可以在配置对象中将 enumerable 的值设置为 true,则使用 Object.defineProperty() 添加的属性可以枚举。
<script>
let person = {
name: 'zs',
sex: 'male'
}
// 向person对象中新添加一个age属性
Object.defineProperty(person, 'age', {
value: 18,
// enumerable 控制属性是否可以枚举,
// 默认值为 false
enumerable: true
})
console.log(person)
console.log(Object.keys(person))
for (let key in person) {
console.log(key, person[key])
}
</script>
描述指定属性是否可修改 writable
- 默认情况下,使用 Object.defineProperty() 添加的属性的值是不可以修改的。

- 要使 Object.defineProperty() 添加的属性值可以修改,在添加属性时,配置对象的 writable 的值设置为 true,使用 Object.defineProperty() 添加的属性值可以修改。
<script>
let person = {
name: 'zs',
sex: 'male'
}
Object.defineProperty(person, 'age', {
value: 18,
enumerable: true,
// 控制属性值是否可以被修改,
// 默认值为 false
writable: true
})
</script>
描述指定属性是否可删除 configurable
- 默认情况下,使用 Object.defineProperty() 添加的属性的值是不可以删除的。

- 要使 Object.defineProperty() 添加的属性值可以删除,在添加属性时,配置对象的 configurable 的值设置为 true,使用 Object.defineProperty() 添加的属性值可以删除。
<script>
let person = {
name: 'zs',
sex: 'male'
}
Object.defineProperty(person, 'age', {
value: 18,
enumerable: true,
writable: true,
// 控制属性是否可以被删除,
// 默认值为 false
configurable: true
})
</script>
访问器描述符 get
- 该描述符的值为一个函数,默认值为 undefined
- 当访问 Object.defineProperty() 中指定的属性时,将不会传递参数地调用 get 对应的函数,函数的 this 指向调用 Object.defineProperty() 中指定属性的对象。函数的返回值将被用作该属性的值。
<script>
let person = {
name: 'zs',
sex: 'male'
}
Object.defineProperty(person, 'age', {
// 当读取person的age属性的时候,
// get函数(getter)会被调用,
// 且函数返回值就是属性age的值
// get: function() {
// console.log('读取age属性')
// return number
// }
// 简写
get() {
console.log('读取age属性')
console.log(this)
return 'hello'
}
})
</script>
访问器描述符 set
- 该描述符的值为一个函数,默认值为 undefined
- 当 Object.defineProperty() 中指定的属性被赋值时,将调用此函数,并带有一个参数(要赋给该属性的值),并将 this 设置为调用 Object.defineProperty() 中指定属性的对象。
<script>
let person = {
name: 'zs',
sex: 'male'
}
Object.defineProperty(person, 'age', {
get() {
console.log('读取age属性')
console.log(this);
return 'hello'
},
// 修改person的age属性的时候,
// set函数(setter)会被调用,
// 且会收到修改的具体值
set(value) {
console.log('修改了age的属性值:', value)
console.log(this);
}
})
</script>
注意点
- Object.defineProperty() 中指定属性的描述符中,不能同时具有 [value 或 writable] 和 [get 或 set],否则会抛出异常
<script>
let person = {
name: 'zs',
sex: 'male'
}
Object.defineProperty(person, 'age', {
value: 12,
get() {
console.log('读取age属性')
console.log(this);
return 'hello'
},
set(value) {
console.log('修改了age的属性值:', value)
console.log(this);
}
})
</script>
Object.defineProperties()
- 该方法用于在一个对象上定义若干个新属性,或者修改若干个对象上已有的属性,并返回修改后的原对象
Object.defineProperties(obj, props)
- 该方法需要传递两个参数:
- obj:需要定义新属性或修改属性的对象
- props:一个对象,其中每个键表示要定义或修改的属性的名称,每个值是描述该属性的对象,在描述该属性的对象中能够配置的描述选项和 Object.defineProperty() 方法中 descriptor 参数一致。
- 该方法返回传入的对象,该对象指定的属性已被新增或修改
- 注意,Object.defineProperties() 和 Object.defineProperty() 一样每个定义的新属性或修改的属性的描述符中不能同时具有 value 或 writable 和 get 或 set 键中的任意一个组合,否则会抛出异常。
const obj = {};
Object.defineProperties(obj, {
property1: {
value: true,
writable: true,
},
property2: {
value: "Hello",
writable: false,
},
// 等等……
});
更多推荐










所有评论(0)