1 作用
冻结一个对象,使对象不可扩展。
2 特性
- 对象的属性不可再被新增、删除
- 对象的属性的值不可再被修改
- 对象的属性的描述符中任意配置项都不可被重新定义
3 代码示例
3.1 冻结对象
Object.freeze()代码如下:
'use strict'
let initialData = {a: 123};
initialData.a = 234;
console.log(initialData.a);
Object.freeze(initialData);
/**
 * 严格模式下会报错
 * TypeError: Cannot assign to read only property 'a' of object '#<Object>'
 */
initialData.a = 345;
console.log(initialData.a);
3.2 冻结判断
Object.isFrozen()代码如下:
//	Object.isFrozen()
Object.isFrozen(initialData);	// true
4 深冻结和浅冻结
直接使用的话只能实现浅冻结,只能冻结第一层。
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>JavaScript - 冻结对象</title>
	</head>
	<body>    
		<script>      
			// 定义一个对象      
			const info = {        
				name: '梦缘',        
				age: 29,        
				hobby: [ '徒步' ]      
			};
      		// 冻结对象      
      		Object.freeze(info);
      		// 新增一个属性:不生效      
      		info.nickname = '熊二';
      		// 删除一个属性:不生效      
      		delete info.name;            
      		// 更改name属性的值:不生效      
      		info.name = '梦念兮';
      		// 更改age属性的值:不生效      
      		info.age = 17;
      		// 更改hobby属性的值:不生效      
      		info.hobby = [ '音乐' ];
      		// 对hobby属性的值添加元素:生效      
      		info.hobby.push('电影');
      		// 打印对象      
      		console.log(info);
      		// 打印对象的每一个属性的描述符      
      		Object.keys(info).forEach(key => {        
      			console.log(Object.getOwnPropertyDescriptor(info, key))      
      		});
      		// 更新属性的【值】描述符:报错      
      		Object.defineProperty(info, 'hobby', {        
      			value: [ '徒步' ]      
      		});
      		// 更新属性的【值是否可更新】描述符:报错      
      		Object.defineProperty(info, 'hobby', {        
      			writable: true      
      		});
      		// 更新属性的【是否可枚举】描述符:报错     
      		Object.defineProperty(info, 'hobby', {        
      			enumerable: false      
      		});
      		// 更新属性的【是否可更改描述符】描述符:报错      
      		Object.defineProperty(info, 'hobby', {        
      			configurable: true      
      		});    
		</script>  
	</body>
</html>效果如下:

其中的hobby属性还是可以进行push。
深冻结需要更深层次操作:
代码如下:
function deepFreeze(obj) {
  // 首先冻结对象本身
  Object.freeze(obj);
  // 获取对象的所有属性
  const props = Object.getOwnPropertyNames(obj);
  // 递归地冻结属性值为对象的属性
  for (const prop of props) {
    const value = obj[prop];
    if (value && typeof value === 'object') {
      deepFreeze(value);
    }
  }
  return obj;
}
// 示例对象
const obj = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4, 5]
  }
};
// 冻结对象
const frozenObj = deepFreeze(obj);
// 尝试修改对象
frozenObj.a = 10;            // 不可修改
frozenObj.b.c = 20;          // 不可修改
frozenObj.b.d.push(6);       // 不可修改
console.log(frozenObj);  // 输出:{a: 1, b: {c: 2, d: [3, 4, 5]}}
5 注意
冻结只会冻结已有的属性,不会拦截到后续添加的属性。如果需要完全禁止属性的添加和删除,可以通过使用Object.seal()函数进行浅冻结,或者使用Object.preventExtensions()函数来禁止对象扩展。



















