Babel针对ES6的指南说:


let是新的var。而var的作用域是当前块。这个答案中有一些很好的例子。

我看不出有任何理由在ES6代码中使用let。即使您希望将给定变量的作用域限定在整个函数中,也可以通过在函数块的顶部放置声明来使用var,无论如何,这是您应该对let进行的操作,以指示实际作用域。而且,如果您想在var块中对某个范围进行更细微的调整,那么您也可以这样做。 br />我的问题是,我对此有误吗?是否存在任何合理的情况,其中forvar更可取?

评论

我还没有尝试过(因为我还没有编写ES6代码),但是似乎使用var作为有意识的指示器来表明该变量的作用域是整个函数,这可能是有用的“自我记录”惯例。

如果将let语句放在函数顶部,我想很明显地打算将其范围限定到整个函数。我不认为使用var可以使它比将其仅放在顶部更清晰。

老实说,我认为var仍然存在的唯一原因是向后兼容。如果不是因为这个原因,他们会完全删除var,或者根本不会引入let,而是将var的语义更改为可以一直认为的。

@RayToal我同意Kyle Simpson所说的97%,但是他继续使用var的原因对我来说似乎很渺茫,不足以保证会有第三种变量出现。您可以简单地通过将let置于整个函数的顶部来将其范围限定在整个函数中,其意图要比在块中写入var要清晰得多(以便将其吊起于该块之外,以便可以在外部使用它街区-很奇怪)。他警告说,如果将let的作用域限定在一个函数上,那么“它只是表明差异的位置,而不是语法”,但是我认为这是一件好事。

@RayToal我也读过这篇文章(在阅读本篇讨论之前),我真的很失望,因为他对var的支持很弱。他为保持var而提出的示例似乎是人为的-都是基于严重的编码错误。遇到错误并被迫修复此类错误比使用使人无法摆脱的语言功能要好得多!接下来,建议将所有内容包装在try / catch中,以防止崩溃?该链接的其余部分都很好,但我完全不同意该特定部分。

#1 楼

Doug Crockford在他的演讲“更好的零件”中讨论了let

关键是,let避免产生误解,尤其是。对于期望通过块范围语言设定的程序员。 var具有函数作用域(它声明了一个在整个函数中可见的变量),即使它看起来像是块作用域。

var也是新功能,并且具有块范围。在const之后,您可以重新分配给let x = {'hi': 'SE'},而在x之后,您不能重新分配给const y = x。这通常是可取的,因为它保留了一些东西(请注意,除非冻结,否则仍然可以修改对象y。)

实际上,您对ES6的印象是正确的:采用y.hi = 'SO'let。停止使用const。(在“更好的零件”的另一种表现中,Doug说为什么添加var而不是解决===的问题。 )

一个显示示例

Mozilla开发人员网络给出了一个示例,其中==不能按预期工作。他们的示例是一个现实的示例,可以在网页中设置==处理程序。这是一个较小的测试用例:相同的函数范围内的===变量,循环结束后的值为var

onclick声明了块作用域变量。
var a = []; (function () { 'use strict'; for (let i = 0; i < 5; ++i) { // *** `let` works as expected *** a.push( function() {return i;} ); } } ()); console.log(a.map( function(f) {return f();} )); // prints [0, 1, 2, 3, 4] // Start over, but change `let` to `var`. // prints [5, 5, 5, 5, 5] 在整个函数中引用相同的变量使我们感到困惑。

评论


对于采用===而不是==,他给出了相同的答案。后者已损坏,但ES标准委员会不想更改它,因此他们添加了===不确定这意味着什么。 ==完全没有中断。可以使用胁迫简单地将其定义为相等比较。请访问github.com/getify/You-Dont-Know-JS/blob/master/…

– AmmarCSE
16年5月12日在3:53



@AmmarCSE是有关隐式强制的出色的39页文档。谁可以在编程时牢记所有这些?正如stackoverflow.com/a/359509/1682419中所概述的,道格的意思是“残破”,简而言之,当值类型的变化超出我们的预期时,该位容易获得。你能预测所有这些吗? ['1.0'== 1.0,[1.0] == 1.0,[1.0] =='1.0',['1.0'] == 1.0,[null] =='',[null] =='null', '00'==否,[] == [],[] == 0,[] =='',[] ==否,[] ==真,[010]-[4] =='4.0 ',!! [0],!! [1],[0] ==真,[1] ==真,1 == [[1]],0 == [[0]],'1'= = [1]

– Jerry101
16年5月12日在6:54



正确,大多数示例涉及数组操作数。当您查看toString及其对对象的实现方式时,很容易理解结果。但是,如果这是损坏的意思,那么我将完全看到损坏的来源。 :-)

– AmmarCSE
16年5月12日在7:53

为什么在不可变时不使用const-只是问问?我的意思是,真正的选择不是在let和var之间,而是在let,var和const之间

– shabunc
16 Jun 30'22:03



var按照设计工作,但没有多少人期望。这是可用性错误,不是实现错误。

– Jerry101
17年4月26日在0:37

#2 楼

如果您一直在编写正确的代码,则可能可以将所有var语句转换为let语句,而无需任何语义更改。
letvar更可取,因为它减小了标识符可见的范围。它使我们能够在首次使用的位置安全地声明变量。
constlet更可取。除非您需要更改引用,否则请使用const声明。这具有let的所有优点,并减少了未初始化变量的存在,并使代码通常更易于推理。如果不确定是否需要突变引用,则将其声明为const,直到发现自己明确需要对其进行突变,然后将其声明为let

#3 楼

我不一定认为您错了,但是使用var有一些警告。本质上,let应该可以帮助开发人员解决JavaScript的愚蠢问题,尤其是在命名冲突方面。 var似乎具有更大的范围,因为它想转到关闭函数范围。有时候,您需要使用var,例如您需要在函数内部的块范围内使用temp变量,否则,优先于var使用let可以帮助开发人员解决命名冲突。简要地说,是ES6推出let的时候了。

评论


整个函数内部都提供块中的临时变量,而不是块范围内的。这是一个误导性功能。

– Jerry101
15年2月24日在23:06

#4 楼

我倾向于同意在es6中仅应使用“ let”。 AFIK,重新声明“ let”会产生错误(这很好),而使用“ var”时,您只需覆盖该值(尽管es5中的“ strict mode”也可以解决该问题)。

#5 楼

let的意思是“让变量相等”。它是一个声明,换句话说,是一个初始化和赋值。

const相反,它的存在当然意味着“常量”-与变量相反。

某些其他语言在声明对象时使用实际对象的前缀而不是对象(例如,def是“定义函数”的简写-完全缺少“ def”的含义)。

Let在Javascript中添加了这种语义上的不一致。

之所以出现此问题,是因为在支持var之前引入了const关键字,因此向后兼容性表明var不一定意味着变量(也可以用来分配常量值)。 br />
因此,在错误的位置引入let为确保我们从词法上记住这是错误的,他们还决定更改letvar的词法范围,因此在调试时我们的想法。

换句话说,存在let是因为人们(意味着语言维护者)认为Javascript过于一致,已经掌握了所有惯用法和特质,渴望更多。表示块为闭包(因为在将块视为闭包之前引入了var),但var确实如此。

评论


-1:学究,无助且主要基于意见。

–乔尔·穆勒(Joel Mueller)
16年4月26日在23:07

fijiaaron在这里只是和我们开玩笑。

– Jerry101
16年5月12日在5:41

我很同情您对词汇形式的不满意,因为它与JavaScript中同一类别中其他关键字的语气不一致。但这仍然不能回答问题,并且放置得也不是很好。不赞成投票

– Aluan Haddad
16-10-20在23:05



不仅仅是开发人员想要更多的复杂性。实际上,从直观上更容易理解,因为当您对vars进行循环并关闭时,闭包将保留var的最后一个值,但是当您对let进行相同的操作时,循环中的每个闭包对于let都有自己的值, la上面@ Jerry101的示例

– TKoL
16-12-28 at 13:33