Skip to content

读者学习到这里,其实会发现,在 JS 中好像并没有常量这个东西,甚至连 C 语言那种宏定义的常量好像也没有学过。实际上,在 ES 5 及之前,要实现常量,用的最多的其实是命名约定,举个例子,那就是我们约定好全大写字母命名的变量的一个常量,你不能修改。但是这只能是一个约定,如果别人想改实际上是可以改掉的。

除了命名约定外,实际上 JS 在 ES 5 及之前还有两种能够达到类似常量效果。

js
function A(){
	var CONST = 1;
	return function(){
		return CONST;
	}
}
var c = A();
//此时执行c()就可以拿到CONST的值,这个CONST可以认为是某种意义下的常量。
//但是这种方式弊端非常明显,就是无法防止对变量c和函数A的覆盖

//我们也可以通过对象来实现类似常量的效果
var obj = {};
Object.defineProperty(obj,"c",{
	value:10,
	enumerable:false,
	writable:false,
});
//这种方式实现后,使用obj.c就可以访问到这个常量,并且obj.c无法被修改和删除,但是问题也存在,那就是我们无法组织对obj本身的覆盖

ES 5 之前的常量实现方式都比较扯淡,但是在 ES 6,JS 引入了常量这个东西,我们可以使用 const 关键字来声明一个常量,const 声明的常量和 let 声明的变量其实是一样的,唯一的区别是 const 声明的是常量,是不可被修改的,当然,这也意味着我们必须在声明时给他赋初值,否则后面就无法再重新赋值。

从命名规范上来说,变量一般用小驼峰式,类、构造函数一般会用大驼峰式,常量则是全字母大写,用下划线分割单词。当然,这只是命名规范,你完全可以不用这个命名规范,只不过可能会被人质疑你的专业素养。但请注意,在 JS 中会优先使用 const 来当做变量,只有确实需要改变的时候才改成 let,此时命名规范可能会有一些不同,只有那些客观不可变的量我们才会使用全大写的命名方式,比如圆周率,比如自然底数。大多数情况下我们虽然使用 const 来定义,但在我们严重它其实还是一个变量。

实际上,在开发中,如果一个量不会被改变,那么应该使用 const 而非 let,这并非硬性规定,这是一种非常优秀的编程习惯,因为 const 的权限比 let 更小,我们其实应该遵循最小权原则,尽可能保证给出去的权限更小,这样系统就会安全很多,使用 const 可以避免变量被疏忽或者恶意篡改,这样可以让我们的代码更加安全,我们也更不容易犯错。

注意,常量不可变是指声明常量的内存空间不可变,看下面的例子

js
const arr = [1,2,3];
arr.push(4);//修改arr数组是没有问题的
arr = 3;//这是不可以的

我们可以这样理解,声明常量后本质上是不能重新赋值,像 arr.push 这种操作其实并不是在给 arr 赋值。

注意,在 for 循环中,循环变量不能使用 const 声明。但在 for...in 循环中是可以使用 const 声明。

以笔记为镜,可以知得失