在JavaScript中的Const?何时使用它是必要的

axd*_*xdg 337 javascript const immutability node.js

我最近在javascript中遇到了const关键字.据我所知,它用于创建不可变变量,我已经测试过以确保它不能重新定义(在node.js中):

const x = 'const';
const x = 'not-const';

// Will give an error: 'constant 'x' has already been defined'
Run Code Online (Sandbox Code Playgroud)

我意识到它还没有在所有浏览器中标准化 - 但我只对node.js/v8的上下文感兴趣,并且我注意到当使用var关键字时,某些开发人员/项目似乎非常喜欢它达到同样的效果.

问题

何时使用const代替var

是否应该在每次声明不会重新分配的变量时使用它?

如果使用var代替const,反之亦然,它实际上是否有任何区别?

Tib*_*bos 452

您的问题有两个方面:使用的技术方面是什么,const而不是var与人类相关的方面是什么.

技术差异很大.在编译语言中,常量将在编译时被替换,并且它的使用将允许其他优化(如死代码删除)以进一步提高代码的运行时效率.最近(松散使用的术语)JavaScript引擎实际上编译JS代码以获得更好的性能,因此使用const关键字将告知它们上述优化是可能的并且应该完成.这导致更好的性能.

与人类相关的方面是关于关键字的语义.变量是包含预期会更改的信息的数据结构.常量是包含永不改变的信息的数据结构.如果有错误的余地,var应始终使用.但是,并非所有在程序生命周期中永远不会更改的信息都需要声明const.如果在不同情况下信息应该更改,请使用var以指示即使实际更改未出现在您的代码中.

  • @Rudie您正在寻找的功能称为[冻结](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)对象.`const`只是阻止将"变量"重新分配给另一个值.`const a = {}; a = {};`将在严格模式下抛出错误. (9认同)
  • `const`对象似乎是可变的,所以我不确定JS编译器到底有多严格.也许"使用严格"模式也有所不同. (5认同)
  • 干杯,我以为Mozilla/Google不会毫无理由地为JS引擎添加const支持.我会确保在适用的地方使用const. (4认同)
  • 变化常数摘要:http://jsfiddle.net/rudiedirkx/6u8p13ev/ (2认同)
  • 如果存在错误的空间,则应始终使用var。如今,这不再适用,ESLint之类的工具立即指出了“ const”违规。 (2认同)

Jam*_*lly 71

2017年更新

这个答案仍然受到很多关注.值得注意的是,这个答案是在2014年初发布的,自那以后发生了很多变化.支持现在已成为常态.所有现代浏览器现在都支持const所以它应该是非常安全的使用没有任何问题.


2014年的原始答案

尽管有相当不错的浏览器支持,但我现在还是避免使用它.来自MDN的文章const:

const的当前实现是特定于Mozilla的扩展,不是ECMAScript 5的一部分.它在Firefox和Chrome(V8)中受支持.从Safari 5.1.7和Opera 12.00开始,如果在这些浏览器中使用const定义变量,您仍可以在以后更改其值.它在Internet Explorer 6-10中不受支持,但包含在Internet Explorer 11中.const关键字当前在函数作用域中声明了常量(就像用var声明的变量一样).

然后继续说:

const将由ECMAScript 6定义,但具有不同的语义.与使用let语句声明的变量类似,使用const声明的常量将是块作用域的.

如果您确实使用const,则必须添加一种变通方法来支持略微较旧的浏览器.

  • 很好的答案 - 虽然我已经阅读了关于MDN的文章.正如我所说,我更感兴趣的是**V8具体**是否真的会以不同的方式对待var.我认为@Tibos清除了这一点. (6认同)
  • 注意ES6已于2014年8月收到功能冻结.2015年7月,该标准正式发布.如果您现在正在阅读此内容,则表示如果您的代码由最新的引擎管理,则应遵循所概述的接受答案. (4认同)

jan*_*nce 38

要集成以前的答案,除了性能原因之外,在声明常量变量方面有明显的优势:如果您不小心尝试在代码中更改或重新声明它们,程序将分别不更改值或抛出错误.

例如,比较:

// Will output 'SECRET'

const x = 'SECRET'
if (x = 'ANOTHER_SECRET') {  // Warning! assigning a value variable in an if condition
    console.log (x)
}
Run Code Online (Sandbox Code Playgroud)

有:

// Will output 'ANOTHER_SECRET'

var y = 'SECRET'
if (y = 'ANOTHER_SECRET') { 
    console.log (y)
}
Run Code Online (Sandbox Code Playgroud)

要么

// Will throw TypeError: const 'x' has already been declared

const x = "SECRET"

/*  complex code */

var x = 0
Run Code Online (Sandbox Code Playgroud)

// Will reassign y and cause trouble

var y = "SECRET"

/*  complex code */

var y = 0
Run Code Online (Sandbox Code Playgroud)


mat*_*001 36

为什么要使用const,@ Tibos的答案很棒.

但你说:

据我所知,它用于创建不可变的变量

那是错的.变量变量与重新分配不同:

var hello = 'world' // assigning
hello = 'bonjour!' // reassigning
Run Code Online (Sandbox Code Playgroud)

使用const,你不能这样做:

const hello = 'world'
hello = 'bonjour!' // error
Run Code Online (Sandbox Code Playgroud)

但你可以改变你的变量:

const marks = [92, 83]
marks.push(95)
console.log(marks) // [92, 83, 95] -> the variable has been mutated.
Run Code Online (Sandbox Code Playgroud)

因此,任何在使用=符号的情况下更改变量值的过程都是静音.

注意:+=例如......重新分配!

var a = 5
a += 2 // is the same as a = a + 2
Run Code Online (Sandbox Code Playgroud)

因此,底线是:const不会阻止您改变变量,它会阻止您重新分配它们.

  • *"但你说:<<从我所知道的,它用于创建不可变的变量>>这是**错误的**.变量变量不同于重新分配"*不,它不是.重新分配正在改变变量.您正在谈论变量引用变量引用的对象.这完全是另一回事. (5认同)
  • 你的陈述"任何改变变量值的过程*没有*使用`=`符号静音"在技术上是错误的.例如,`const marks = [92,83]; 马克[2] = 95; console.log(marks)`将输出`[92,83,95]`.`标记'已通过等号变异. (3认同)
  • @Y 代码没有。当您使用“const countArray”时,它*永远不会*被重新分配。您仍然可以推送到数组,这会更改其成员和长度,但我们不称之为重新分配。当您想防止重新分配时,可以使用“const”而不是“let”或“var”。顺便说一句,如果您“确实”想要允许重新分配,“let”几乎总是比“var”更好。 (2认同)

Ant*_*ony 31

const不是一成不变的.

来自MDN:

const声明创建对值的只读引用.它并不意味着它拥有的值是不可变的,只是不能重新赋值变量标识符.

  • 但这有点误导.对于数字,字符串,布尔值等(原语)`const`是不可变的.对于对象和数组,它不能被重新分配,但可以更改内容(例如array.push). (21认同)
  • JS原语总是不可变的.你是否使用`const`不会影响它. (2认同)

Sri*_*hna 12

var:声明一个变量,值初始化可选.

let:使用块作用域声明局部变量.

const:声明一个只读的命名常量.

例如:

var a;
a = 1;
a = 2;//re-initialize possible
var a = 3;//re-declare
console.log(a);//3

let b;
b = 5;
b = 6;//re-initiliaze possible
// let b = 7; //re-declare not possible
console.log(b);

// const c;
// c = 9;   //initialization and declaration at same place
const c = 9;
// const c = 9;// re-declare and initialization is not possible
console.log(c);//9
// NOTE: Constants can be declared with uppercase or lowercase, but a common
// convention is to use all-uppercase letters.
Run Code Online (Sandbox Code Playgroud)


Edg*_*ant 10

你有很好的答案,但让我们保持简单.

const 当你有一个已定义的常量时应该使用(读作:在程序执行期间它不会改变).

例如:

const pi = 3.1415926535
Run Code Online (Sandbox Code Playgroud)

如果您认为以后执行时可能会更改某些内容,请使用a var.

基于这个例子的实际差异在于,const你将始终认为pi将是3.14 [...],这是事实.

如果将其定义为a var,则可能是3.14 [...].

对于更具技术性的答案,@ Tibos在学术上是正确的.


Fun*_*ing 7

根据我的经验,当我想设置一些我可能想要稍后改变的东西时,我使用const而不必寻找已经硬编码的代码,例如文件路径或服务器名称.

测试中的错误是另一回事,你要创建另一个名为x的变量,这将是一个更准确的测试.

const x = 'const';
x = 'not-const';
Run Code Online (Sandbox Code Playgroud)

  • 我理解你的意思,但是 - 对你而言,"不变"意味着"我可能想要改变的事情",这很有趣.:P (7认同)