JavaScript中的常量:什么时候使用它,有必要吗?

2020/09/30 23:41 · javascript ·  · 0评论

我最近遇到过constJavaScript中关键字。据我所知,它用于创建不可变变量,并且我已进行测试以确保不能重新定义它(在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反之亦然吗?

您的问题有两个方面:const代替使用的技术方面是var什么以及与人相关的方面是什么。

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

与人有关的方面与关键字的语义有关。变量是一种数据结构,其中包含预期会更改的信息。常量是一种数据结构,其中包含永远不变的信息。如果有错误的余地,var应始终使用。但是,并非必须使用声明所有在程序生存期内从未改变的信息const如果在不同的情况下信息应该更改,var即使实际的更改未出现在您的代码中,也请使用该信息进行指示。

2017更新

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


2014年的原始答案

尽管有相当不错的浏览器支持,但我暂时避免使用它。来自MDN的文章const

当前const的实现是Mozilla特定的扩展,不属于ECMAScript5。它在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,@Tibos的答案很棒。

但是你说:

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

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

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

使用const,您不能这样做:

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

但是您可以更改变量:

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

因此,任何在使用=符号的情况下更改变量值的过程都会使变量变异。

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

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

因此,最重要的是:const不会阻止您对变量进行变异,而是会阻止您重新分配变量

要集成先前的答案,除了性能原因外,在声明常量变量方面还有一个明显的优势:如果您不小心尝试在代码中更改或重新声明它们,则程序将不会分别更改值或引发错误。

例如,比较:

// 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声明创建对值的只读引用。这并不意味着它拥有的值是不变的,只是不能重新分配变量标识符。

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.

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

const 当您有一个已定义的常量时,应使用(读为:在程序执行期间它不会更改)。

例如:

const pi = 3.1415926535

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

根据示例,实际的区别在于,const您总是会假设pi为3.14 [...],这是事实。

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

对于更多的技术答案,@ Tibos在学术上是正确的。

In my experience I use const when I want to set something I may want to change later without having to hunt through the code looking for bits that have been hard coded e.g. A file path or server name.

The error in your testing is another thing though, you are tring to make another variable called x, this would be a more accurate test.

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

确实是个人喜好。如您所说,可以在不重新分配常量且常量的情况下使用const。例如,如果您想分配生日。您的生日永远不会改变,因此您可以将其用作常量。但是您的年龄确实发生了变化,因此可能会有所不同。

概要:

const创建一个不可变的绑定,这意味着const变量标识符不可重新分配。

const a = "value1";

您不能用

a = "value2";

但是,如果const标识符包含一个对象或数组,则只要我们不重新分配它,就可以更改其值。

const x = { a: 1 }

x.a = 2; //is possible and allowed

const numbers = [1, 2];
numbers.push(3); //is possible and allowed

请注意,const是一个块级作用域,就像let一样,var(它是函数作用域)不同

简而言之,当某些事情不太可能通过重新分配改变时,请使用const,否则根据您希望的范围使用letvar

当代码死了很明显时,通过重新分配可以更改哪些内容以及不能更改哪些内容,就可以更容易地对代码进行推理。将const更改为let非常简单。默认情况下使用const会使您在进行此操作之前三思而后行。在许多情况下,这是一件好事。

它提供:1)常量引用,例如const x = []-可以修改数组,但x不能指向另一个数组;和2)区块范围。const和let将一起在ecma6 / 2015中替换var参见https://strongloop.com/strongblog/es6-variable-declarations/中的讨论

Main point is that how to decide which one identifier should be used during development.
In java-script here are three identifiers.

1. var (Can re-declared & re-initialize)
2. const (Can't re-declared & re-initialize, can update array values by using push)
3. let (Can re-initialize but can't re-declare)

'var':在编写代码标准时,我们通常使用标识符的名称,其他用户/开发人员很容易理解这个标识符。例如,如果我们正在考虑使用许多函数,其中使用一些输入并对其进行处理并返回一些结果,例如:

**Example of variable use**

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2;
 return result;
}

在上面的示例中,两个函数产生不同的2结果,但使用相同的变量名。在这里我们可以看到'process'和'result'都被用作变量,它们应该被使用。

 **Example of constant with variable**

 const tax = 10; 
 const pi = 3.1415926535; 

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

在Java脚本中使用“让”之前,我们必须在js文件顶部添加“使用严格”

 **Example of let with constant & variable**

 const tax = 10; 
 const pi = 3.1415926535; 
 let trackExecution = '';

function firstFunction(input1,input2)
{
 trackExecution += 'On firstFunction'; 
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 trackExecution += 'On otherFunction'; # can add current time 
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

 firstFunction();
 otherFunction();
 console.log(trackExecution);

在上面的示例中,您可以跟踪在特定操作期间何时使用哪个功能以及何时不使用哪个功能。

首先,有三点有用的东西const(除了与之共享的范围改进之外let):

  • 它为以后阅读代码的人们提供了证明,该值不得更改。
  • 它可以防止您(或任何追随您的人)更改值,除非他们返回并有意更改声明。
  • 可以为JavaScript引擎节省一些优化方面的分析。例如,您已经声明该值不能更改,因此引擎无需做任何工作来确定该值是否更改,因此它可以根据未更改的值来决定是否进行优化。

你的问题:

什么时候适合const代替var

可以做任何你声明一个变量,其值永远不会改变的时间。您是否认为合适完全取决于您的偏好/团队的偏好。

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

这取决于您/您的团队。

如果var is used in place ofconst`或反之则实际上有什么区别吗?

是:

  • varconst具有不同的范围规则。(您可能想与let而不是进行比较var。)特别是:const并且let它们是块范围的,并且在全局范围内使用时,不要在全局对象上创建属性(即使它们确实创建了全局变量)。var具有全局范围(在全局范围内使用时)或函数范围(即使在块中使用),并且在全局范围内使用时,会在全局对象上创建属性。
  • 参见上面的“三件事”,它们都适用于此问题。

的语义varlet

var并向let机器和其他程序员声明:

我打算在执行过程中更改此赋值。不要依赖此分配的最终值。

使用var和的含义let

varlet迫使其他程序员读取从声明到最终使用的所有中间代码,并在程序执行的那一刻说明赋值的原因。

它们削弱了ESLint和其他语言服务的机器推理能力,从而可以在以后的分配中正确检测类型错误的变量名,并在内部作用域忘记声明的情况下重新使用外部作用域变量名的作用域。

它们还使运行时在所有代码路径上运行许多迭代,以在对其进行优化之前检测到它们实际上实际上是常量。尽管这比错误检测和开发人员可理解性要小得多。

何时使用 const

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

const”对象

对于对象引用,不能将指针更改为另一个对象,但是创建并分配给const声明的对象可变的。您可以添加或删除const引用数组中的项目,并在const引用的对象进行

要实现不可变的对象(这又使代码易于为人和机器推理),可以Object.freeze在声明/分配/创建处使用该对象,如下所示:

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

Object.freeze确实会影响性能,但是由于其他原因,您的代码可能会变慢。您要分析它。

您还可以将可变对象封装在状态机中,并将深层副本作为值返回(这是Redux和React状态的工作方式)。有关如何根据基本原理构建此状态的示例,请参见在Browser JS中避免使用可变的全局状态

什么时候varlet很好

letvar代表可变状态。在我看来,它们应该仅用于模拟实际可变状态诸如“连接是否还存在? ”之类的信息。

这些最好封装在可测试的状态机中,这些状态机公开表示“连接的当前状态常量值,该常量在任何时间点都是常量,而其余代码实际上是您感兴趣的。

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

有关更细微的解释,请参见《突变的信徒-案例》const

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

我不是JS编译行业的专家,但是可以说,v8在const标志中使用

通常,在声明并更改了一堆变量之后,内存会碎片化,并且v8停止执行,暂停几秒钟,以进行gc或垃圾回收。

如果使用const v8声明了变量,则可以放心将其放在其他const变量之间的固定大小固定容器中,因为它永远不会改变。由于类型不会更改,因此它还可以保存该数据类型的正确操作。

我的意见:

问:什么时候可以const代替var

答:从不!

问:是否应在每次声明一个不会被重新分配的变量时使用它?

答:永远不会!
这样会减少资源消耗...

问:如果var使用它代替const或反之,实际上有什么区别吗?

A:是的!
使用
var是必经之路!开发工具更加轻松,并且无需创建新文件进行测试即可保存。var代替const-const试图var取代...)

额外-答:同样适用letJavaScript是一种宽松的语言-为什么要const泛滥?!?

letconst(两个块都作用域)之间进行决策时,请始终首选const,以便在代码中清楚使用。这样,如果您尝试重新声明该变量,则会收到错误消息。如果没有其他选择,只能重新声明,只需切换为let即可请注意,正如Anthony所说,const值不是一成不变的(例如,const对象可以使属性发生突变)。

关于var,由于ES6已经发布,所以我从未在生产代码中使用过它,也没有想到它的用例。可以考虑使用它的一点是JavaScript托管-虽然不提升letconst,但声明var但是,请注意,用var声明的变量 具有函数作用域,而不是块作用域(“如果在任何函数外部声明,它们将在整个程序中全局可用;如果在函数内部声明,则它们仅在函数本身中可用”,在HackerRank中-变量声明关键字)。您可以将let作为var的块作用域版本

本文地址:http://javascript.askforanswer.com/javascriptzhongdechangliangshenmeshihoushiyongtayoubiyaoma.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!