var obj = {
a: 2
}
// 获取描述符对象
var l = Object.getOwnPropertyDescriptor(obj, 'a')
console.log(l);//{ value: 2, writable: true, enumerable: true, configurable: true }
// 参数依次为属性所在对象、属性名、一个描述符对象
Object.defineProperty(obj, 'b', {
value: 12,
// 可配置的
writable: true,
// 可遍历的
enumerable: true,
// 可配置的
configurable: true
})
console.log(obj);//{ a: 2, b: 12 }
Object.defineProperty(obj, 'a', {
writable: true,
enumerable: true,
configurable: false
})
// configurable设置为false是单向操作,下面的代码会保存
Object.defineProperty(obj, 'a', {
writable: true,
enumerable: true,
configurable: true
})
obj.a =44
console.log(obj);//Cannot redefine property: a
不变性的一些方法总结:
var foo = {}
Object.defineProperty(foo, 'MY_NUMBER', {
value: 22,
// 不可修改
writable: false,
// 不可配置
configurable: false
})
var foo = {
a: 2
}
// 禁止一个对象添加新属性并保留已有属性
Object.preventExtensions(foo)
foo.b = 22
// 无法添加属性,严格模式报错
console.log(foo);//{ a: 2 }
var foo = {
a: 2
}
// 无法添加新属性、无法重新配置或删除属性,可以修改
Object.seal(foo)
var foo = {
a: 2
}
// 比起seal,它将使对象的所有属性的数据属性的writable设置为false
// 即属性不能修改,数据属性不可配置,不能添加属性,删除属性,修改属性
Object.freeze(foo)
注意: 上面的操作并未实现深度冻结,对于对象中属性值为引用类型的数据将不会受到影响,仍可修改
var foo = {
a: 2,
b: [3, 4, 5]
}
Object.freeze(foo)
foo.b[0] = 333
//可以修改
console.log(foo);//{ a: 2, b: [ 333, 4, 5 ] }
实现深度冻结的方法和深拷贝的方法一样,通过遍历判断属性中的引用类型的值并对其调用freeze方法