JS中对象的冻结和封闭
本文首发于个人博客 Cyy’s Blog
转载请注明出处 https://cyyjs.top/blog/60991bcde676b5000ec60c05
当我们使用JavaScript
定义一个对象时,这个对象可以随意修改的;如添加新的属性,更改属性值等,那我们如何能将这个对象锁定,使其不能对属性值进行修改,或删除属性呢?JavaScript
的API
有两个方法,给我们提供了类似的能力。
# Object.freeze()
该方法接收一个对象作为参数,作用是将传入的参数进行冻结。冻结后的对象,不能添加新的属性,不能删除已有属性,不能修改属性值,也不能修改属性的可枚举性、可配置性、可写性;并且此对象的原型也不能修改。
操作对象例子:
let obj = {
a: 1,
b: 2
}
console.log(obj)
// {a: 1, b: 2}
Object.freeze(obj)
// 修改a的值
obj.a = 2
console.log(obj)
// {a: 1, b: 2} a的值没有修改成功
// 添加新属性
obj.c = 3
console.log(obj)
// {a: 1, b: 2} c没有添加成功
// 删除属性a
delete obj.a
console.log(obj)
// {a: 1, b: 2} a没有删除成功
// 修改a的值
Object.defineProperty(obj, 'a', {value: 2})
// 报错
操作数组例子:
let arr = [1, 2]
console.log(arr)
// [1, 2]
Object.freeze(arr)
// 修改第一个元素的值
arr[0] = 2
console.log(arr)
// [1, 2] 值没有修改成功
// 修改a的值
arr[2] = 3
console.log(arr)
// [1, 2] 没有添加成功
// push操作
arr.push(3)
// 报错
// pop操作
arr.pop()
// 报错
// 修改length
arr.length = 10
console.log(arr.length)
// 2
// 修改无效
# Object.seal()
该方法为封闭一个对象,与Object.freeze()
类似,此方法可以阻止对象添加新属性,并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
操作对象的例子:
let obj = {
a: 1,
b: 2
}
console.log(obj)
// {a: 1, b: 2}
Object.seal(obj)
// 修改a的值
obj.a = 2
console.log(obj)
// {a: 2, b: 2} 修改成功
// 添加c
obj.c = 3
console.log(obj)
// {a: 2, b: 2} c没有添加成功
// 删除属性a
delete obj.a
console.log(obj)
// {a: 2, b: 2} a没有删除成功
// 修改a为不可写
Object.defineProperty(obj, 'a', {writable: false})
// 成功
obj.a = 1
console.log(obj)
// {a: 2, b: 2} a没有修改成功
操作数组例子:
let arr = [1, 2]
console.log(arr)
// [1, 2]
Object.seal(arr)
// 修改第一个元素的值
arr[0] = 2
console.log(arr)
// [2, 2] 修改成功
// 修改a的值
arr[2] = 3
console.log(arr)
// [1, 2] 没有添加成功
// push操作
arr.push(3)
// 报错
// pop操作
arr.pop()
// 报错
// 修改length
arr.length = 10
console.log(arr.length)
// 10
// 修改成功
# 嵌套的对象或数组
需要注意的是,上述两个方法只对对象或数组的第一层生效,嵌套的数组或对象是不生效的;
例如:
let obj = {
a: 1,
b: {
c: 1
}
}
Object.freeze(obj)
obj.b = {} // 未改变
obj.b.a = 1 // 添加属性a成功
let arr = [1, [2]]
Object.freeze(obj)
arr[1].push(2) // push成功