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); } }; |
上一篇:uniapp中web-view页面H5与App跨平台双向通信
下一篇:Vue3 中新特性—toRaw与markRaw之间区别
支付宝扫一扫打赏
微信扫一扫打赏
共 0 条评论关于"Object.freeze(obj)冻结一个对象或者数组,使其不能发生变化"
最新评论