JS_Object.freeze 冻结对象

什么是Object.freeze

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;

  • 冻结了一个对象则不能向这个对象添加新的属性
  • 不能删除已有属性
  • 不能修改该对象已有属性的可枚举性、可配置性、可写性,
  • 不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改
    freeze() 返回和传入的参数相同的对象

作用

Object.freeze()是ES5新增的特性,可以冻结一个对象,防止对象被修改。
vue 1.0.18+对其提供了支持,对于data或vuex里使用freeze冻结了的对象,vue不会做getter和setter的转换。
如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升。在我的实际开发中,这种提升大约有5~10倍,倍数随着数据量递增。

Object.freeze基本使用

var obj = {
	name:'alley',
	age:19,
	sex:'男'
}

obj.__proto__.habit = '运动';

Object.freeze(obj);

// 不能添加新属性
obj.address = '北京'
console.log(obj)    // {name: "alley", age: 19, sex: "男"}
 
// 不能删除原有属性
delete obj.age
console.log(obj)    // {name: "alley", age: 19, sex: "男"}
 
// 不能修改已有属性的值
obj.name = 'dy_alley'
console.log(obj)    // {name: "alley", age: 19, sex: "男"} 

// 不能修改原型
obj.__proto__ = '随便什么值'
console.log(obj.__proto__)  // {habit: "运动", constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, …}

// 不能修改已有属性的可枚举性、可配置性、可写性
Object.defineProperty(obj,'name',{ // TypeError: Cannot redefine property: address
    enumerable: false,
    configurable: false,
    writable: true
})

冻结数组

var arr = [1,2,3,4,5,6];
Object.freeze(arr);
arr[0] = 'alley'; 
console.log(arr); // [ 1,2,3,4,5]. 

深度冻结

Object.freeze只能进行浅冻结,如果对象里面有对象的情况下则无法冻结

var obj = {
    name:'alley',
    info: {
      age:19,
      sex:'男'
    }
}
Object.freeze(obj);
obj.name = 'dy_alley';
obj.info.age = 20;
console.log(obj); // {name:'alley',info:{age:20,sex:'男'}};

通过递归来进行深度冻结

function deepFreeze(obj) {
   /*
     Object.getOwnPropertyNames()与Object.keys()的区别:

         Object.getOwnPropertyNames返回的是对象中所有自己的属性;
         Object.keys(obj)则返回的对象中所有自己的属性,也就是属性下的 enumerable: true 的属性

         const obj = {};
         Object.defineProperties(obj, {
               name: {enumerable: true, value: 'alley'},
               age: {enumerable: false, value: 25},
         })

         console.dir(Object.keys(obj))
         console.dir(Object.getOwnPropertyNames(obj))

         输出
         > Array ["name"]
         > Array ["name", "age"]
 */
   var propsNames = Object.getOwnPropertyNames(obj);
   propsNames.forEach((item)=>{
       var props = obj[item];
       if(props instanceof Object && props !==null) {
           deepFreeze(props);
       }
   })

   return Object.freeze(obj);
}

获取对象是否冻结

Object.isFrozen(obj)

Object.freeze原理

模拟Object.freeze原理主要用到了2个方法, Object.definedProperty()、Object.seal()
Object.definedProperty方法可以定义对象属性的特性
Object.seal 可以让对象不能被扩展

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值