Object.freeze()如何使const定义的复杂数据类型不可更改数据结构

发布时间 2023-09-05 10:46:15作者: 码磊姐姐

const本质

引用阮一峰的话:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
我们都知道const的值是不可以改变的,但是当定义一个对象时,就可以间接改变对象里的值,就像这样

const arr={};
arr={name:'Marry'}//会报错
arr.name='Marry'//不会报错,而且现在arr会变成{name:'Marry'};

我还试了一个复杂的对象数据类型:

const arr = {
  name:'Tina',
  info:[
    {name:'marry',age:20},
    {name:'simone',age:10}
    ],
  address:'China'
};
 arr.info[0].name='小明';//此时arr对象中的info数组的第一个对象的name值会变成‘小明’===>{name: '小明', age: 20}

所以这个时候我们的数据可能随时都会改变,那么怎么才能不被改变呢?
可以用Object.freeze()方法将对象冻结。如果你的对象知识普通的对象。里面没有嵌套结构,就可以直接用Object.freeze(对象),如果对象是像我上面定义的那样比较复杂,就可以用下面的方法

const freezeFun = function(obj)=>{
  Object.freeze(obj);
  Object.keys(obj).forEach((key)=>{
  if(typeof obj[key]==='object'){
    freezeFun(obj[key]);
    }
  })
}

//这个时候我们再想改变对象的值就不可能了,因为对象以及被完全冻结了
const arr = {
  name:'Tina',
  info:[
    {name:'marry',age:20},
    {name:'simone',age:10}
    ],
  address:'China'
};
freezeFun(arr);//调用冻结函数
arr.info[0].name='小红'//此时以及无法修改了

感兴趣的朋友可以玩一玩~