Object.freeze() 的使用

前言

Object.freeze()方法可以冻结一个对象,被冻结后的对象是:不能再向这个对象添加新的属性,不能修改原有属性值,不能删除已有属性,不能修改已有属性的可枚举性、可配置性、可写性。

一、基本使用

正常对象操作:

var obj = {name:'小米',age:25,address:'地址'};
obj.sex = '男'; //添加属性sex
obj.age = 26;  //修改age的值
delete obj.address;  //删除属性address
console.log(obj);  // {age:26,name:'小米',sex:"男"}

使用Object.freeze()冻结对象:

var obj = {name:'小米',age:25,address:'地址'};
obj.__proto__.title = '原型';
Object.freeze(obj);  //冻结对象obj
obj.age = 30;  //修改原有属性
console.log(obj,'1');
//{name: "小米", age: 25, address: "地址"} "1" //不能修改成功
obj.sex = '男';  //添加新的属性
console.log(obj,'2'); 
//{name: "小米", age: 25, address: "地址"} "2" //不能添加新属性
delete obj.address; //删除已有属性
console.log(obj,'3');
//{name: "小米", age: 25, address: "地址"} "3" //不能删除已有属性
Object.defineProperty(obj,'age',{
	enumerable:false,
	configurable:false,
	writable:true
}) //不能修改已有属性的可枚举性、可配置性、可写性
console.log(obj,'4') //Cannot redefine property: age

Object.isFrozen()判断对象是否被冻结:

var data = {name:'小小',title:'信息'};
var newObj = Object.freeze(data);
console.log(newObj === data,'判读对象是否一致'); //true
console.log(Object.isFrozen(data),'判读data是否被冻结') //true
console.log(Object.isFrozen(newObj),'判读newObj是否被冻结')//true
var newData = {name:'梨梨'}
console.log(Object.isFrozen(newData),'判读newData是否被冻结')//false

冻结数组:

var arr = [1,23,34,2];
Object.freeze(arr);
arr[0] = '修改';
console.log(arr);
//Identifier 'arr' has already been declared

二、浅冻结和深冻结

1.浅冻结

如上所说,Object.freeze()可以冻结简单的对象,如果对象里还有对象,那么冻结还有效吗?

var obj={name:'小米',info:{title:'新闻',value:100}};
Object.freeze(obj);
obj.name='mm';
console.log(obj);
//{name:'小米',info:{title:'新闻',value:100}}
obj.info.value = 200;
console.log(obj);
//{name:'小米',info:{title:'新闻',value:200}}

以上所示,当对象中的属性为对象时,Object.freeze()失效了。

Object.freeze()只支持浅拷贝。

2.深冻结

function deepFreeze(obj){
	//获取对象属性名称
	let names = Object.getOwnPropertyNames(obj);
	names.forEach(item =>{
		let data = obj[item];
		if(data instanceof Object && data !== null){
			deepFreeze(data)
		}
	})
	return Object.freeze(obj)
}
let dataAll = {name:'小米',info:{value:120,title:'xxx'}};
deepFreeze(dataAll);
dataAll.info.value = 200;
console.log(dataAll);
//{name:'小米',info:{value:120,title:'xxx'}}

三、Object.freeze()原理

Object.freeze()主要是用到以下两个方法:

Object.defineProperty():可以定义对象的属性是不是可以删除,修改等。

Object,seal():可以阻止添加新的属性,不能修改。

Object.defineProperty(person, 'name', {
    configurable: false,// 表示能否通过delete删除属性,能否修改属性的特性...
    enumerable: false,// 表示是否可以枚举。直接在对象上定义的属性,基本默认true
    writable: false,// 表示能否修改属性的值。直接在对象上定义的属性,基本默认true
    value: 'xm'// 表示属性的值。访问属性时从这里读取,修改属性时,也保存在这里。
})

总结

如果对象内容很多,都是静态数据,而且不会修改它,那可以用Object.freeze()冻结起来。这样可以让性能大幅提升,提升的效果随着数据量的递增而递增。对于纯展示的大数据,都可以使用Object.freeze提升性能。

在vue项目中,data初始化里面一般会有很多变量,后续如果不想使用它,可以使用Object.freeze()。这样可以避免vue初始化的时候,做一些无用的操作,从而提高性能。

猜你喜欢

转载自blog.csdn.net/zyf971020/article/details/127510294