为啥 var 不被弃用?

Posted

技术标签:

【中文标题】为啥 var 不被弃用?【英文标题】:Why is var not deprecated?为什么 var 不被弃用? 【发布时间】:2018-05-08 00:15:34 【问题描述】:

在 ES6 发布后不久,许多消息来源建议我使用“const”和“let”而不是“var”,并且我应该停止在我的 javascript 中使用“var”。

我想知道的是,如果“var”在所有方面都比“let”没有优势,那么他们为什么不直接修复 var,甚至弃用“var”,而不是让它们并排?

【问题讨论】:

因为更改或删除它会破坏大约十亿行代码。 varlet 更有用,当您需要函数作用域而不是块作用域时。 var仍有用处。 所以你的用例是在块内声明一个变量,然后在块外使用它? @jhpratt 在任何一家优秀的公司都无法通过代码审查......而且肯定会被任何 linter 盖章。 【参考方案1】:

向后兼容性。

您说得对,使用 var 比使用 let 没有真正的优势 - 如果您在函数开头定义它们,它们的含义基本相同。

您是对的,没有真正的理由使用var 编写新代码(可能除了this,如果相关)。

虽然互联网上有些页面已有数十年的历史,但没有人会重写它们。从语言中删除 var 并没有什么真正的好处。对于 html 和 Javascript 等被解释的语言 - 向后兼容是绝对必要的。

这也是他们选择不简单地重新定义var 的原因。以下面的示例代码为例;

// THIS IS AN EXAMPLE OF BAD CODE. DO NOT COPY AND PASTE THIS.
if (logic) 
    var output = "true"
 else 
    var output = "false"

console.log(output)

如果将var 更改为类似于let 的行为,那么console.log 将由于范围差异而导致引用错误。

【讨论】:

感谢您的回答。我很感激。然而,您的回答只能解决问题的一部分,即“为什么不弃用 var”。从一开始就重构“var”而不引入任何“let”怎么样?有充分的理由吗? 再次,向后兼容。如果人们以您问题的 cmets 中描述的可怕方式使用var(并且确实发生了),那么该代码将改变含义并中断,就编写它的开发人员而言可能没有警告。跨度> 我添加了一个例子。 我一直认为你展示的例子是错误的形式。最好在更高的范围内声明变量。这意味着我不认为这是一个很好的使用 var 的例子。 我同意 - 也许我应该让这一点更明显。然而,这是一个例子,说明为什么将 var 更改为意味着 let 是一个坏主意,这就是意图。【参考方案2】:

使用 var const 和 let 各有优缺点。

var

变量声明在代码执行之前被处理。 用 var 声明的 JavaScript 变量的范围是它当前的执行上下文。 在函数外部声明的 JavaScript 变量的作用域是全局的。

let

let 语句允许您创建一个变量,其范围仅限于使用它的块。

const

const 语句的值可以被赋值一次并且不能被重新赋值。 const 语句的作用域类似于 let 语句。

希望你能理解。

【讨论】:

您没有列出 var 的任何优势。您也可以在函数或全局级别使用let,那么除了做一些不愉快的事情(例如在块中声明var,然后在该块之外使用它)之外,优势在哪里。 "变量声明在代码执行前处理" - the same is true for let and const 请注意,“变量声明”包括 letconst(根据 ECMA-262 §13.3.1),它们都在代码执行之前被处理(但是执行代码时进行分配)。 ;-)【参考方案3】:

我相信有时你需要重新声明一个变量来编写更少的代码。

一个例子是这个生成唯一ID的函数:

function makeUniqueId(takenIds) 
  do 
    var id = Number.parseInt(Math.random() * 10);
   while (takenIds.includes(id))

可以这样调用

makeUniqueId([1,2,3,4,5,6,7])

在这里,我在 do 块内声明了 id 变量,它被“提升”到函数范围。如果我使用let,那会导致错误,因为while 块不会看到do 块中的变量。当然,我可以在 do..while 之前声明 let,但这会使用额外的代码行创建相同的函数作用域变量。

另一个示例是当您将代码复制粘贴到 devtools 控制台并且每次重新声明变量时。

另一个例子。如果你想让你的变量声明接近它们的用法,但仍将它们视为函数全局变量怎么办?如果您以这种方式使用let,您将在开发工具(所有这些块、块范围)中获得相当混乱的体验。

但是var 将它们“保持”在一个“本地”列表中:

【讨论】:

"如您所见,id 可能会被重新声明很多次......" 不会。当控制进入新的执行上下文(或块范围声明的块)时,声明只被处理一次。在执行 makeUniqueId 的任何主体之前,变量 id 存在于函数范围内。没有 while 块,有一个 while 表达式,你是对的,do 中的 let 声明的范围..while 循环不会扩展到 while 条件,因此如果在块。 感谢收看! 所有这些用例都不足以成为保留 var 的理由。它带来的混乱和错误多于好处。简化将不胜感激。 所有例子都展示了完全相反的情况:[例如。 1]:id的逻辑是在外部作用域,必须在外部声明,而不是在do,然后使用let 上面; [前任。 2]:复制粘贴重新声明的变量是极其危险的;使用 let 将明确显示问题; [前任。 3]类似于1:你说你想声明一个接近其用法的变量,但你想把它当作全局变量:因此声明必须在全局范围内。一般来说,使用全局变量是不明智的,除非在模块模式中,即 const 声明的对象。

以上是关于为啥 var 不被弃用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Vector 和 HashTable 被广泛认为应该被弃用? [复制]

为啥 Vector 和 HashTable 被广泛认为应该被弃用? [复制]

为啥 std::rel_ops::operators 在 C++20 中会被弃用?

为啥(以及赞成啥)maven-bundle-plugin 的 wrap/bundleall 目标被弃用?

@angular-cli 安装失败,请求被弃用@2.88.2:请求已被弃用(mac)

弃用警告:executable_path 已被弃用 selenium python