如果Babel将let和const转换为var,有什么区别吗?

3
我尝试过 babel transpiler,它会将所有的let、const和var转换为var,那么总体上来说,在我们的代码使用中有什么区别呢?
我已经阅读了文档,我知道let、const和var之间的区别,但如果它们最终都被转换成var,那还有什么区别呢?这意味着在性能甚至作用域方面都不应该有任何有意义的差异!

更新(2019年2月14日):根据答案,我理解作用域确实很重要,即使它们被转换为var,babel也保留了作用域的含义。我的问题仍然是关于性能方面是否有任何有意义的区别

我附上了转译器的输入和输出,以及一个更复杂的场景
输入

let a = 1;

for (let a = 0; a !== 0;) {
  for (let a = 0; a !== 0;) {}
}

输出

"use strict";

var a = 1;

for (var _a = 0; _a !== 0;) {
  for (var _a2 = 0; _a2 !== 0;) {}
}

在一个代码块 {} 中声明 let 和尝试在代码块外部访问它之间存在差异。对于 var,重复相同的操作。它可能会将所有内容转换为 var,但是对于 let 和 const,我非常确定有特殊规则适用。这个问题并没有询问任何有意义的东西,如果你说你知道它们之间的区别,那么这个问题根本就没有必要存在。 - squeekyDave
3
这可能会有所帮助。https://bambielli.com/til/2017-04-04-let-transpilation/# - Saraband
1
并非所有的Babel配置都会将“const”和“let”转换为“var”。但是这个问题仍然是合理的。 - rishat
@squeekyDave,我更新了我的问题以反映评论中提到的内容,但是我的关于性能的问题仍然存在。Babel仍将它们全部转换为var,只是使用一些规则来保持作用域的含义。如果它们都是var,那么在性能上是否有任何区别? - Masoud Tahmasebi
@rml 抱歉,我不知道它在哪些配置下无法转换它们? - Masoud Tahmasebi
2个回答

12

Babel将ES6语法转换为ES5语法(或者你正在处理的JS源版本和目标版本)。

这通常会丢失代码中的某些细微差别,但是您正在查看一个非常琐碎的例子。

相反,请考虑以下内容:

let x = 1;

{
  // Inside a block, this is a different x
  let x = 2; 
  console.log(x);
}

console.log(x);

Babel会将其转换为:

"use strict";

var x = 1;
{
  // Inside a block, this is a different x
  var _x = 2;
  console.log(_x);
}
console.log(x);

看看它如何将内部的x重新命名,以避免覆盖外部的变量?

它尽可能地在ES5中表达ES6的效果,即使结果很丑陋(因为ES6的优美特性不可用)。


谢谢,我只是有一个快速的问题,有没有任何性能差异? - Masoud Tahmasebi
在什么之间?在哪种JS引擎中?谨防过早优化 - Quentin
在ES6应用程序中使用var和let之间存在差异,在所有JS引擎中都是如此。因为最终它们会被转换为var,但是对于这个问题有一些疑问,有人说使用let和const确实会有所不同。非常棒的关于过早优化的文章,非常感谢。 - Masoud Tahmasebi

3

Babel会对每个变量进行检查,如果违反了某些过程规则,则会抛出错误。例如,如果定义了一个const,并且稍后更改了值,这将违反类型的规则。另一个例子是在已经存在的作用域中重新定义变量(这可能是同名函数)。在某些情况下,Babel仅仅会重命名以防止冲突。


我认为它也检查输出目标,<es6不支持let。但是我可能错了。 - Get Off My Lawn
那么它仅用于类型目的,而不是任何性能优化? - Masoud Tahmasebi
我怀疑不是这样的。这主要涉及代码质量和便利性。不过这是另一个问题了。 - isherwood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接