常量在JavaScript? 什么时候使用它,这是必要的

我最近在javascript中遇到了const关键字。 从我可以告诉,它被用来创build不可变的variables ,我已经testing,以确保它不能被重新定义(在node.js中):

const x = 'const'; const x = 'not-const'; // Will give an error: 'constant 'x' has already been defined' 

我意识到它在所有的浏览器中都还没有被标准化 – 但是我只对node.js / v8的上下文感兴趣,而且我注意到当var关键字可以被使用时,某些开发者/达到相同的效果。

问题

什么时候可以使用const代替var

是否应该每次使用一个不会被重新分配的variables被声明?

如果使用var代替const ,反之亦然?

12 Solutions collect form web for “常量在JavaScript? 什么时候使用它,这是必要的”

你的问题有两个方面:使用const而不是var的技术方面是什么,以及与此相关的与人有关的方面是什么。

技术上的差异是显着的。 在编译语言中,常量将在编译时被replace,并且其使用将允许进行其他优化,如去除死代码以进一步提高代码的运行效率。 最近(松散地使用的术语)JavaScript引擎实际上编译JS代码以获得更好的性能,所以使用const关键字会告诉他们上面描述的优化是可能的并且应该完成。 这导致更好的性能。

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

2017更新

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


2014年的原始答复

尽pipe有相当不错的浏览器支持 ,我现在要避免使用它。 从MDN的关于const的文章 :

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

然后它继续说:

const将被ECMAScript 6定义,但是具有不同的语义。 类似于用let语句声明的variables,用const声明的常量将是块范围的。

如果你使用const你将不得不添加一个解决方法来支持稍旧的浏览器。

为了整合以前的答案,除了性能原因之外,声明常量variables还有一个明显的优势:如果不小心尝试在代码中更改或重新声明它们,则程序将分别不更改值或抛出错误。

例如,比较:

 // Will output 'SECRET' const x = 'SECRET' if (x = 'ANOTHER_SECRET') { // Warning! assigning a value variable in an if condition console.log (x) } 

有:

 // Will output 'ANOTHER_SECRET' var y = 'SECRET' if (y = 'ANOTHER_SECRET') { console.log (y) } 

要么

 // Will throw TypeError: const 'x' has already been declared const x = "SECRET" /* complex code */ var x = 0 

 // Will reassign y and cause trouble var y = "SECRET" /* complex code */ var y = 0 

const 不是不可变的。

从MDN :

const声明为一个值创build一个只读引用。 这并不意味着它所拥有的价值是不可变的,只是variables标识符不能被重新分配。

为什么要使用const ,@ Tibos的答案很好。

但你说:

从我可以告诉的是,它被用来创build不可变的variables

这是错误的 。 变更variables与重新分配不同:

 var hello = 'world' // assigning hello = 'bonjour!' // reassigning 

用const,你不能这样做:

 const hello = 'world' hello = 'bonjour!' // error 

但是你可以改变你的variables:

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

所以,任何改变variables值而不使用=符号的进程都是静音的。

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

 var a = 5 a += 2 // is the same as a = a + 2 

所以,底线是: const不会阻止你对variables进行变异 ,它会阻止你重新赋值

在我的经验中,我使用const时,我想设置一些我可能想稍后改变,而不必寻找代码已经被硬编码,如文件path或服务器名称寻找代码。

然而,testing中的错误是另一回事,你正打算做另一个名为x的variables,这将是一个更准确的testing。

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

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

当你有一个定义的常量时,应该使用const (读作:在你的程序执行过程中不会改变)。

例如:

 const pi = 3.1415926535 

如果你认为这是在稍后的执行中可能会改变的东西,那么使用var

基于这个例子,实际的区别在于,用const你总是会认为pi是3.14,这是事实。

如果将其定义为var ,则可能是3.14 […]或不。

对于更技术性的答案@Tibos在学术上是对的。

个人喜好真的。 你可以使用const,正如你所说的,它不会被重新赋值并且是常量。 例如,如果你想分配你的生日。 你的生日永远不会改变,所以你可以使用它作为一个常数。 但是你的年龄确实发生了变化,所以可能是一个variables。

它提供了:1)一个常量引用,例如const x = [] – 该数组可以被修改,但是x不能指向另一个数组; 和2)阻止范围界定。 const和let将会一起replaceecma6 / 2015中的var请参阅https://strongloop.com/strongblog/es6-variable-declarations/

首先,关于const三个有用的东西(除了它与let分享的范围改进之外):

  • 它为稍后阅读代码的人提供了文档,该值不能改变。
  • 它可以防止你(或者任何追随你的人)改变价值,除非他们故意回头修改声明。
  • 可能会在优化方面保存JavaScript引擎的一些分析。 例如,你已经声明了这个值是不能改变的,所以引擎不需要做任何的工作来判断这个值是否改变,所以可以根据这个值不改变来决定是否进行优化。

你的问题:

什么时候可以使用const代替var

可以在任何时候声明一个值永不改变的variables。 无论你认为适当的完全取决于你的偏好/你的团队的偏好。

是否应该每次使用一个不会被重新分配的variables被声明?

这取决于你/你的团队。

如果使用var is used in place of const,反之亦然?

是:

  • varconst有不同的作用域规则。 (你可能想用let而不是var来比较)。特别是: constlet是块范围的,当在全局范围使用时,不要在全局对象上创build属性(即使它们创build全局variables)。 var具有全局作用域(在全局作用域中使用)或函数作用域(即使在块中使用),并且在全局作用域中使用时,将在全局对象上创build一个属性。
  • 看到我上面的“三件有用的东西”,它们都适用于这个问题。

'const'表示你的代码标识符不会被重新分配。 这是一篇关于何时使用'const','let'或'var'的好文章https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.ukgxpfhao

我不是JS编译业务方面的专家,但是有理由说,v8使用const标志

通常情况下,声明和更改一堆variables后,内存被分割,v8停止执行,暂停几秒钟,以进行gc或垃圾收集。

如果一个variables声明为const,那么v8可以放心地把它放在其他constvariables之间的一个紧密的固定大小的容器中,因为它永远不会改变。 它也可以保存该数据types的正确操作,因为types不会改变。

  • 使用Node.JS,我如何读取(服务器)内存的JSON对象?
  • console.log和node.js中的sys.puts之间的区别?
  • 一旦你完成,正确closuresmongoose的连接
  • 在安装后运行业力导致“业力”不被识别为内部或外部命令
  • 节点包(Grunt)已安装但不可用
  • 如何在javascript / Node.js中获取一天的时间?
  • Express.js路由:可选spat参数?
  • 如何使用Node.js解决“无法find模块”错误?
  • Express.js:如何获取远程客户端地址
  • Node.js的SSH客户端
  • 如何在JSDoc中指定承诺的parsing和拒绝types?