JS 使用const声明常量的本质(很多人都有误解)
在我们使用const声明常量时,总认为值一旦声明就不可改变,其实是有误解的;
刚在看ES6标准文档时,仔细阅读了const的解析,恍然大悟的感觉,分享给大家。
本质
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。
但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = ;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
上面代码中,常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。
下面是另一个例子。
const a = [];
a.push('Hello'); // 可执行
a.length = ; // 可执行
a = ['Dave']; // 报错
上面代码中,常量a是一个数组,这个数组本身是可写的,但是如果将另一个数组赋值给a,就会报错。
如果真的想将对象冻结,应该使用Object.freeze方法。
const foo = Object.freeze({});
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = ;
上面代码中,常量foo指向一个冻结的对象,所以添加新属性不起作用,严格模式时还会报错。
除了将对象本身冻结,对象的属性也应该冻结。下面是一个将对象彻底冻结的函数。
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};
JS 使用const声明常量的本质(很多人都有误解)的更多相关文章
- 上传伪技术~很多人都以为判断了后缀,判断了ContentType,判断了头文件就真的安全了。是吗?
今天群里有人聊图片上传,简单说下自己的经验(大牛勿喷) 0.如果你的方法里面是有指定路径的,记得一定要过滤../,比如你把 aa文件夹设置了权限,一些类似于exe,asp,php之类的文件不能执行,那 ...
- 很多人都在埋怨没有遇到好的团队,但好的团队不可能凭空出现,一流的团队不能仅靠团队成员努力,作为Leader,要有可行的规划,并坚定地执行、时势地调整(转)
<西游记>中的唐僧团队历经千难万险,终于求得真经,目标明确.分工合理为这支队伍最终走向成功奠定了基础.唐僧从一开始,就为这个团队设定了西天取经的目标,虽然经历各种挫折与磨难,但目标从未动摇 ...
- [转帖](区块链补习班)ERC20很多人都听过,但ERC是什么你真的了解吗?
(区块链补习班)ERC20很多人都听过,但ERC是什么你真的了解吗? http://baijiahao.baidu.com/s?id=1600948969290990883&wfr=spide ...
- 听说特斯拉花了4个月研发出新ERP,然后很多人都疯了
欢迎关注微信公众号:sap_gui (ERP咨询顾问之家) 最近这件事儿在SAP圈里炒的挺火的,最主要是因为这几个关键词: 放弃SAP.4个月.自研ERP: 这则新闻一出来,很多人都兴高采烈,都要疯了 ...
- ES6学习之const声明常量的学习
在ES中const关键字用来声明常量,const声明的一经定义不能修改 和let特性差不多, ; console.log(a); a = ; //报错 const定义完常量后必须赋值,后面不允许再次赋 ...
- 震惊!很多人都不知道 CSS Grid 框架早就有了!
前言 写作本文起源于知乎的一个问题:[CSS Grid 布局那么好,为什么至今没有人开发出基于 Grid 布局的前端框架呢?] 这篇文章拖沓了两个月,是因为真的不知道从哪里说好.这个问题的所有回答几乎 ...
- 很多人都搞不清楚C语言和C++的关系!今天我们来一探究竟为大家解惑~
最近,身边有许多小伙伴已经开始学习编程了,但是呢,学习又会碰到许多的问题,其中作为新手小白提到最多的问题就是编程语言的选择. 每次遇到这种问题,看起来很简单,但是又有很多小伙伴搞不清编程语言之间的关系 ...
- 很多人都不知道的监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法
版权声明:本文为博主原创文章,未经博主允许不得转载. 在实际的应用中,我们常常需要实现在移动app和浏览器中点击返回.后退.上一页等按钮实现自己的关闭页面.调整到指定页面或执行一些其它操作的 需求,那 ...
- 原来现在很多人都用SignalR来实现Chat Room
今天从一个业余开发的群里,看到有人要求这样一个项目需求: 1,)学员可以通过在线课堂找到自己喜欢的老师和课程. 2,)每个人可以建立自己课堂,每个课堂扣分多个子房间,交流群.设置管理员:有录音功能,可 ...
随机推荐
- Selenium上传文件方法总结
Web上本地上传图片,弹出的框Selenium是无法识别的,也就是说,selenium本身没有直接的方法去实现上传本地文件,这里总结了两种上传文件的方式. 一.利用Robot类处理文件上传. 其大致流 ...
- django项目的新建相关的命令及配置
创建工程 django-admin startproject 工程名称 运行开发服务器 python manage.py runserver 创建子应用 python manage.py st ...
- javascript中的常用表单事件用法
下面介绍几种javascript中常用的表单事件: 一,onsubmit:表单中的确认按钮被点击时发生的事件,如下案例. 案例解析:弹出表单中提交的内容 <form name="tes ...
- Codeforces899D Shovel Sale(思路)
http://codeforces.com/problemset/problem/899/D 还是得tag一下,以下代码只有G++ 14 6.4.0能过,其他都过不了不知为什么? 思路:先求出最多的9 ...
- CentOS下双网卡双IP不同IP段配置
环境: eth0:10.0.7.2 gw :10.0.7.254 netmask:255.255.255.0 eth1:168.6.101.2 gw :168.6.101.254 net ...
- Go语言排序算法实现
// Algorithm project Algorithm.go package Algorithm // 冒泡排序 func BubbleSort(a []int) { n := len(a) ; ...
- windows10创建ftp服务器
1.创建用户 2.创建FTP服务 3.开通防火墙服务 建立端口21,20入站规则 4.访问测试
- 解决Android Studio出现GC overhead limit exceeded
方法一: 修改项目目录下的gradle.properties,增加如下配置信息(红色文字中需要根据自己电脑的配置修改内存大小,其余的配置用于加快gradle的编译速度) org.gradle.daem ...
- window系统命令行设置proxy----Setting a proxy for Windows using the command-line
设置代理, bypass-list的参数是不走代理地址: netsh winhttp set proxy proxy-server="socks=localhost:9090" b ...
- nrm管理npm源
npm源:npm install命令下载需要依赖包的服务器地址,默认是 npm ---- https://registry.npmjs.org/ 而国外的源速度太慢,所以我们一般都用国内的淘宝源tao ...