唯品秀前端博客

Object.freeze可以用来冻结一个对象或者一个数组,冻结的是对象本身,冻结后的对象或者数组不能被修改,不能添加新的属性 ,不能删除已有属性,不能修改已有属性的值,返回值是被冻结的对象本身,与被冻结的源对象完全一致,也被冻结

冻结一个对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
let obj = {
  "name": "张三",
  "age": 18,
  "sex": '男'
}

let _obj = Object.freeze(obj)

console.log(_obj) // 返回值是被冻结的对象自身,没有任何变化
// {name: "张三", age: 18, sex: "男"}

// 尝试修改?
obj.name = "李四"
obj.school = "加里敦大学"
delete obj.sex

// 不能修改、添加、删除已有属性的值,最终还是返回原来这个对象本身
console.log(obj)
// {name: "张三", age: 18, sex: "男"}

console.log(_obj) // 返回值与被冻结的源对象完全一致
// {name: "张三", age: 18, sex: "男"}

_obj.age = 19

console.log(obj)
// {name: "张三", age: 18, sex: "男"}

console.log(_obj) // 返回值也被冻结
// {name: "张三", age: 18, sex: "男"}

浅冻结

方法冻结的是对象或数组,如果其属性的属性值是数组(子)或者对象(子),可以修改数组(子)或对象(子)的属性值,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let obj = {
  name: "zhangsan",
  interest: ["boll","book","music"]
}

let _obj = Object.freeze(obj)

obj.interest[2] = "food"

obj.interest.push("teach")

console.log(obj) // 可以修改数组(子)中的属性值,对象也是同理
// {name: "zhangsan", interest: ["boll", "book", "food", "teach"]}

console.log(_obj) // 浅拷贝
// {name: "zhangsan", interest: ["boll", "book", "food", "teach"]}

深冻结

要使对象深层不可变,需要递归冻结每个类型为对象的属性(深冻结)。当你知道对象在引用图中不包含任何 环 (循环引用)时,将根据你的设计逐个使用该模式,否则将触发无限循环。对 deepFreeze() 的增强将是具有接收路径(例如Array)参数的内部函数,以便当对象进入不变时,可以递归地调用 deepFreeze() 。你仍然有冻结不应冻结的对象的风险,例如[window]。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 深冻结函数.
function deepFreeze(obj) {

  // 取回定义在obj上的属性名
  var propNames = Object.getOwnPropertyNames(obj);

  // 在冻结自身之前冻结属性
  propNames.forEach(function(name) {
    var prop = obj[name];

    // 如果prop是个对象,冻结它
    if (typeof prop == 'object' && prop !== null)
      deepFreeze(prop);
  });

  // 冻结自身(no-op if already frozen)
  return Object.freeze(obj);
}

obj2 = {
  internal: {}
};

deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // undefined

冻结数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let arr = ["zhangsan","lisi","wangwu"]

let _arr = Object.freeze(arr) // 可以冻结数组

console.log(_arr) // 返回值与原数组一致
// ["zhangsan", "lisi", "wangwu"]

arr[0] = "maliu"

arr[4] = "shengqi"

// arr.push("shengqi") // 注意,这个位置会报错,控制台会告诉你该数组不允许添加新的成员

console.log(arr)  // 冻结后不可以修改、添加和删除
// ["zhangsan", "lisi", "wangwu"]

console.log(_arr)
// ["zhangsan", "lisi", "wangwu"]

_arr[1] = "yunba"

console.log(arr)
// ["zhangsan", "lisi", "wangwu"]

console.log(_arr); // 返回值也不可以修改、添加和删除
// ["zhangsan", "lisi", "wangwu"]

小结

通常来讲使用这个东西机会不是很多,但某些时候假设我们需要做代码的性能优化就可能用到它,例如从服务器获取一个列表信息,列表只在初始化时候请求显示,后期不需要改变,这个时候就可以通过该方法冻结ajax拿到后的数据对象,不需要对数据做响应化处理,可以大大提升渲染速度

1
2
3
4
5
6
7
8
9
export default {
 data: () => ({
   list: []
}),
 async created() {
   const userList = await axios.get("/api/users");
   this.list = Object.freeze(userList);
}
};
本站所有文章、图片、资源等如无特殊说明或标注,均为来自互联网或者站长原创,版权归原作者所有;仅作为个人学习、研究以及欣赏!如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,邮箱:343049466@qq.com
赞(29) 打赏
标签:

上一篇:

下一篇:

相关推荐

0 条评论关于"Object.freeze(obj)冻结一个对象或者数组,使其不能发生变化"

表情

最新评论

    暂无留言哦~~
谢谢你请我吃鸡腿*^_^*

支付宝扫一扫打赏

微信扫一扫打赏