万万没想到!ES6的const并非一定为常量

栏目: JavaScript · 发布时间: 6年前

内容简介:摘要:const定义的变量一定为常量吗?No!对于ES6的const变量,大家一直存在误会,这篇博客将试着解开真相。const定义的变量并非常量,并非不可变。使用const定义的对象或者数组,其实是可变的。下面的代码并不会报错:

摘要:const定义的变量一定为常量吗?No!

对于ES6的const变量,大家一直存在误会,这篇博客将试着解开真相。

const的本质

const定义的变量并非常量,并非不可变。使用const定义的对象或者数组,其实是可变的。下面的代码并不会报错:

const foo = {};
foo.name = "Fundebug";
console.log(foo.name); // 打印"Fundebug"

为什么会这样?下面引用大神阮一峰的 ECMAScript 6 入门

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

因此,当我们使用 赋值运算符 , 一元运算符 以及 后缀运算符 对const变量进行修改时,会出现 “TypeError:Assignment to constant variable” 报错:

const foo = 27;

// 下面任意一个表达式都会报错:TypeError: Assignment to constant variable.
foo = 42; 
foo *= 42;
foo /= 42;
foo %= 42;
foo += 42;
foo -= 42;
foo <<= 0b101010;
foo >>= 0b101010;
foo >>>= 0b101010;
foo &= 0b101010;
foo ^= 0b101010;
foo |= 0b101010;


--foo;
++foo;


foo--;
foo++;

如果你需要监控线上应用的BUG的话,欢迎免费试用Fundebug。

如何定义常量?

对于数值、字符串和布尔值变量,使用const定义的话是不可变的:

const name = "Fundebug";
name = "云麒"; // 报错:TypeError: Assignment to constant variable.

使用 Object.freeze() 可以让对象不可变,这个API从ES5开始就有了。

const foo = Object.freeze(
{
    'name': "Fundebug"
});

foo.name = "云麒"; // 严格模式("use strict")下报错:Uncaught TypeError: Cannot assign to read only property 'bar' of object '#<Object>'

console.log(foo.name); // 非严格模式下打印"Fundebug"

注意,Object.freeze()是有局限性的,对象中嵌套对象仍然可以被修改。MDN提供了一下 deepFreeze 示例代码,是利用Object.freeze()实现的,可以让嵌套对象也不可变。

另外,Object.freeze()仅对键值对有效。对于Date, Map和Set,目前还没有相应方法。因此有人 提议 在ECMAScript标准中添加不可变的Map和Set等数据类型。

const和let如何选择?

const和let的唯一区别在于,const可以让数值、字符串和布尔变量不可变。

以上所说的内容都是事实,下面我想表达一下自己的观点。

const可以提高代码的可读性,因为const定义的数值、字符串和布尔变量是不可变的,而const定义的对象始终指向同一个对象。而使用let时,不能保证这些。因此,对于let和const,我们应该这样选择:

  • 默认使用const
  • 仅当变量需要修改时使用let
  • 不要使用var

你是否同意我的观点呢?欢迎大家交流讨论~

参考

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏,Node.js和 Java 实时BUG监控。

自从2016年双十一正式上线,Fundebug累计处理了5亿+错误事件,得到了众多知名用户的认可。欢迎免费试用!

万万没想到!ES6的const并非一定为常量

版权声明:
转载时请注明作者<b><a href="https://fundebug.com" target="_blank" title="Fundebug">Fundebug</a></b>以及本文地址:
<b><a href="https://blog.fundebug.com/2018/07/25/es6-const/" target="_blank" title="万万没想到!ES6的const并非一定为常量">https://blog.fundebug.com/2018/07/25/es6-const/</a></b>

您的用户遇到BUG了吗?

体验Demo 免费使用

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Wireshark网络分析实战

Wireshark网络分析实战

[以色列 Yoram Orzach / 古宏霞、孙余强 / 人民邮电出版社 / 2015-1 / 79.00元

本书采用步骤式为读者讲解了一些使用Wireshark来解决网络实际问题的技巧。 本书共分为14章,其内容涵盖了Wireshark的基础知识,抓包过滤器的用法,显示过滤器的用法,基本/高级信息统计工具的用法,Expert Info工具的用法,Wiresahrk在Ethernet、LAN及无线LAN中的用法,ARP和IP故障分析,TCP/UDP故障分析,HTTP和DNS故障分析,企业网应用程序行......一起来看看 《Wireshark网络分析实战》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换