Object.defineProperty
是 JavaScript 提供的 精确控制对象属性行为 的方法。它允许我们定义或修改对象的属性,并且可以设置该属性的 可写性(writable)、可配置性(configurable)和可枚举性(enumerable)。
Object.defineProperty(obj, prop, descriptor)
obj
:要定义或修改属性的对象。prop
:要定义或修改的属性名称(字符串)。descriptor
:一个描述符对象,定义该属性的行为。let person = {}
Object.defineProperty(person, "name", {
value: "Alice",
writable: false, // 不可修改
configurable: false, // 不可删除或重新定义
enumerable: true // 可枚举
})
console.log(person.name) // "Alice"
person.name = "Bob" // 由于 writable: false,不会修改
console.log(person.name) // 仍然是 "Alice"
描述符对象可以包含以下几个属性:
value
(属性值)Object.defineProperty(obj, "key", { value: "hello" })
console.log(obj.key) // "hello"
writable
(是否可写)false
,表示 不能修改该属性。let obj = {}
Object.defineProperty(obj, "x", {
value: 10,
writable: false
})
obj.x = 20 // 赋值失败
console.log(obj.x) // 仍然是 10
enumerable
(是否可枚举)false
,表示 该属性不会出现在 for...in
或 Object.keys(obj)
结果中。let obj = {}
Object.defineProperty(obj, "secret", {
value: "hidden",
enumerable: false
})
console.log(Object.keys(obj)) // []
console.log(obj.secret) // "hidden"
configurable
(是否可重新定义或删除)false
,表示 无法删除该属性,也无法重新定义它。let obj = {}
Object.defineProperty(obj, "id", {
value: 100,
configurable: false
})
delete obj.id // 删除失败
console.log(obj.id) // 仍然是 100
get
& set
)除了 value
,我们还可以使用 getter 和 setter 来定义动态计算属性。
let user = {
firstName: "John",
lastName: "Doe"
}
Object.defineProperty(user, "fullName", {
get() {
return this.firstName + " " + this.lastName
},
set(value) {
[this.firstName, this.lastName] = value.split(" ")
}
})
console.log(user.fullName) // "John Doe"
user.fullName = "Alice Smith"
console.log(user.firstName) // "Alice"
console.log(user.lastName) // "Smith"
get()
:每次访问 fullName
时,都会执行 get
方法,动态计算值。set(value)
:允许修改 fullName
,并将输入拆分成 firstName
和 lastName
。普通赋值(obj.prop = value
) 只能设置值,而 Object.defineProperty
可以:
writable: false
)。enumerable: false
)。configurable: false
)。getter/setter
处理动态计算。const settings = {}
Object.defineProperty(settings, "apiUrl", {
value: "https://api.example.com",
writable: false
})
settings.apiUrl = "https://new-api.com" // 失败
console.log(settings.apiUrl) // 仍然是 "https://api.example.com"
const user = { name: "Alice" }
Object.defineProperty(user, "password", {
value: "secret123",
enumerable: false
})
console.log(Object.keys(user)) // ["name"],password 不会出现
console.log(user.password) // 仍然可以访问 "secret123"
let cart = { price: 100, quantity: 2 }
Object.defineProperty(cart, "total", {
get() {
return this.price * this.quantity
}
})
console.log(cart.total) // 200
cart.quantity = 3
console.log(cart.total) // 300(自动更新)
特性 | 作用 |
---|---|
value |
定义属性的默认值 |
writable |
是否可修改值(默认 false ) |
enumerable |
是否能被 for...in 或 Object.keys() 访问(默认 false ) |
configurable |
是否能删除或重新定义(默认 false ) |
get() |
计算属性的 getter |
set(value) |
计算属性的 setter |
Object.defineProperty
?writable: false
)。enumerable: false
)。如果你只是想简单地给对象添加属性,普通赋值 obj.key = value
就够了。但如果你需要更细粒度的控制,就可以用 Object.defineProperty
!