我最近在JavaScript中遇到了const关键字。据我所知,它是用来创建不可变变量的,我已经测试了,以确保它不能被重新定义(在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比较合适? 它是否应该被用在每一个不存在的变量上 重新分配是声明的? 如果用var来代替,会有什么不同吗 Const还是反之?


当前回答

var:声明一个变量。值初始化是可选的。

let:声明一个块范围的局部变量。

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

例子:

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

let b;
b = 5;
b = 6; // Reinitialise possible
// let b = 7; // Redeclare not possible
console.log(b);

// const c;
// c = 9;    // Initialization and declaration at the same place
const c = 9;
// const c = 9; // Redeclare 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.

其他回答

当涉及到let和const(都是块作用域)之间的决定时,总是首选const,以便在代码中使用清楚。这样,如果您试图重新声明变量,就会得到一个错误。如果没有其他选择,只能重新声明它,只需转换为let。注意,正如Anthony所说,const值不是不可变的(例如,const对象的属性可以发生变化)。

When it comes to var, since ES6 is out, I never used it in production code and can't think of a use case for it. One point that might consider one to use it is JavaScript hoisting - while let and const are not hoisted, var declaration is. Yet, beware that variables declared with var have a function scope, not a block scope («if declared outside any function, they will be globally available throughout the program; if declared within a function, they are only available within the function itself», in HackerRank - Variable Declaration Keywords). You can think of let as the block scoped version of var.

var:声明一个变量。值初始化是可选的。

let:声明一个块范围的局部变量。

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

例子:

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

let b;
b = 5;
b = 6; // Reinitialise possible
// let b = 7; // Redeclare not possible
console.log(b);

// const c;
// c = 9;    // Initialization and declaration at the same place
const c = 9;
// const c = 9; // Redeclare 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.

var和let的语义

Var和let是对机器和其他程序员的声明:

我希望这个赋值在执行过程中发生变化。不要依赖于这个赋值的最终值。

使用var和let的含义

Var,并强制其他程序员读取从声明到最终使用的所有中间代码,并在程序执行时推断赋值的值。

它们削弱了ESLint和其他语言服务的机器推理,从而在以后的赋值中正确检测输入错误的变量名,并在内部作用域忘记声明的情况下对外部作用域变量名进行作用域重用。

它们还导致运行时在所有代码路径上运行多次迭代,以检测它们实际上是常量,然后才能优化它们。尽管这比错误检测和开发人员可理解性的问题要小。

何时使用const

如果引用的值在执行过程中没有改变,那么表达程序员意图的正确语法是const。对于对象,改变引用的值意味着指向另一个对象,因为引用是不可变的,而对象不是。

“常量”对象

对于对象引用,指针不能更改为另一个对象,但创建并赋值给const声明的对象是可变的。可以从const引用的数组中添加或删除项,也可以更改const引用对象的属性键。

为了实现不可变对象(同样,这使你的代码更容易为人类和机器推理),你可以object .freeze对象在声明/赋值/创建,像这样:

const Options = Object.freeze(['YES', 'NO'])

freeze确实对性能有影响,但您的代码可能因为其他原因而变慢。你想要侧写它。

你也可以将可变对象封装在状态机中,并返回深度副本作为值(这就是Redux和React状态的工作方式)。有关如何从第一原则构建全局状态的示例,请参见避免在Browser JS中使用可变全局状态。

当var和let是一个很好的匹配

Let和var表示可变状态。在我看来,它们应该只用于建模实际的可变状态。比如“连接是否存在?”

这些最好封装在可测试的状态机中,这些状态机公开了表示“连接的当前状态”(在任何时间点都是常数)的常量值,以及代码的其余部分真正感兴趣的内容。

加上合成副作用和转换数据,编程已经够难了。通过创建带有变量的可变状态将每个函数变成不可测试的状态机只会增加复杂性。

要了解更细致的解释,请参见Shun the Mutant - const的案例。

2017年更新

这个答案仍然受到很多关注。值得注意的是,这个答案是在2014年初发布的,从那时起发生了很多变化。Ecmascript-6支持现在是标准。所有现代浏览器现在都支持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,你将不得不添加一个变通方法来支持稍微老一点的浏览器。

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

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

The human-related aspect is about the semantics of the keyword. A variable is a data structure that contains information that is expected to change. A constant is a data structure that contains information that will never change. If there is room for error, var should always be used. However, not all information that never changes in the lifetime of a program needs to be declared with const. If under different circumstances the information should change, use var to indicate that, even if the actual change doesn't appear in your code.