谈谈const跟Object.freeze()
自发布以来,ES6为JavaScript带来了一些新特性和方法。这些新特性可以极大地改善我们开发人员的编码方式,提高生产力。今天我们来聊聊Object.freeze()
方法和const
。
有人认为这两个新特性在功能上重复了,其实不然。Object.freeze()
和const
的使用场景是有区别的,听我慢慢道来。
先来看看字面上的区别:
-
const
表现像let
。唯一的区别是,它定义的变量无法再次赋值。const
声明的变量具有块级作用域。它偏向于变量指向的内存地址不可变。 -
Object.freeze()
将一个对象作为参数,返回同一个对象的immutable
版本。这意味着我们希望不能添加,删除或更改此对象的任何属性。它偏向于对象不可变。
mutable对象具有可以更改的属性。immutable对象创建后便不可以更改属性。
可能光说内存地址不可变跟对象不可变还是有点抽象哈,我们来看几块代码就明白了。
来看个例子:
const
const user = 'zong'
user = 'jacob'
我们试图给使用const
关键字声明的变量user重新赋值,但这是一个无效的操作,会抛出一个Uncaught TypeError
异常。
只有var
或let
声明的变量才能重新赋值。
const的问题
当声明对象时,使用const仅防止再次赋值,但不保证不可变性(immutable),也就是不能防止更改其属性的值。
const
仅仅只能保证
const user = {
name: 'xxx'
}// won't work
我们无法对这个变量再次赋值。
但是我们可以修改这个对象本身,比如下面这段代码:
const user = {
name: 'zong',
email: 'hizong@xxx.com',
country: 'China',
}
user.last_name = 'jacob';
但这有时候并不是我们想要的,我们不希望我们的对象被修改,这时候 Object.freeze()
就派上用场了。
Object.freeze()
为了禁止对对象进行修改,我们需要使用 Object.freeze()
。
const user = {
name: 'zong',
email: 'hizong@xxx.com',
country: 'China',
}
Object.freeze(user)
user.name='xxx' //won't work
console.log(user)
Object.freeze()的问题
1.它是一个浅操作
要注意的是, Object.freeze()
是一个浅操作, 如果user某个属性是一个对象,那我们是需要递归地去应用它来确保整个user对象是不可修改的。
const user = {
name: 'zong',
contact: {
email: 'hi@xxx.com',
mobile: 000000,
}
}
Object.freeze(user);
user.name= 'jacob' //won't work
user.contact.telephone = 111111 //work
console.log(user)
所以当一个对象某个属性也是一个对象时,Object.freeze()
并没有完全freeze 一个对象。
要完全让一个对象不可变,我们得自己递归处理或者使用Deepfreeze或immutable-js这样的库。
2. 我们还可以对变量重新赋值
Object.freeze()
仅仅让传入它的对象immutable
,让我们无法修改它的属性,但是它没有规定我们不能修改变量指向的对象,也就是我们可以给变量重新赋值。
let user = {
name: 'zong',
contact: {
email: 'hi@xxx.com',
mobile: 000000,
}
}
Object.freeze(user);
console.log(user)
user={
name:'xxx'
}
console.log(user)
我们可以看到,如果我们用let
去声明了一个变量,尽管经过Object.freeze()
处理后,它指向的对象属性不可修改,但我们仍可以重新赋值。如果是const声明的变量,那就不行了。
到这儿我们就彻底搞清楚它们的区别啦,const
侧重于变量指向的内存地址不可变,Object.freeze()
侧重于生成的对象属性不可变。两者结合有可能实现一个内存地址,属性都不可变的对象。
- POJ2488-A Knight's Journey(DFS+回溯)
- FreeMarker快速入门
- 用只含一个链域的节点实现循环链表的双向遍历
- 亚马逊注册3个新域名引发预测,或成为最大数字货币交易所
- POJ-1979 Red and Black(DFS)
- 06-图2 Saving James Bond - Easy Version
- 06-图1 列出连通集
- Bootstrap快速入门
- 常用工具(Windows版本)
- Hadoop快速入门
- Lake Counting(POJ-2386)
- Vue快速入门
- 04-树6. Huffman Codes--优先队列(堆)在哈夫曼树与哈夫曼编码上的应用
- SpringAOP实战应用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一分钟速学 | NMS, IOU 与 SoftMax
- [译] 使用 TypeScript 开发 React Hooks
- 磁盘空间分析神器 - ncdu
- Kafka笔记—可靠性、幂等性和事务
- 工程能力UP!| LightGBM的调参与并行
- 你想要的Android性能优化系列:启动优化 !
- 微信小程序的自定义组件(入门)
- linux 中关于PAM的点滴笔记
- 49. Vue使用axios发送Ajax请求
- UCSC-browser学习:创建自己的track hubs
- 五分钟快速搭建Serverless免费邮件服务
- 基于qiankun落地部署微前端爬”坑“记
- Android推送的群魔乱舞
- 用百度接口实现图片文字识别,并打包成安装包软件
- 视野前端(二)V8引擎是如何工作的