为什么Babel不能正确处理const?

0 javascript const ecmascript-6 babeljs

检查下面的代码.计数器声明为const.当你运行它时,它不应该允许它在任何情况下改变!

function increment(counter) {
 counter += 1; 
}

function test() {
    const counter = 1;
    increment(counter);
}
Run Code Online (Sandbox Code Playgroud)

转换后,它会生成以下代码.这允许const计数器递增!

function increment(counter) {
  counter += 1; // Counter is declared const, still it can be changed!
}

function test() {
  var counter = 1;
  increment(counter);
}
Run Code Online (Sandbox Code Playgroud)

我只是试图理解,无论是Babel转换还是JavaScript规范都存在问题.

编辑: 我知道,与ES6不同,当前版本的JS不支持const.我担心的是,如果我使用已编译的JavaScript,我可能会遇到未知的const相关错误.那可以吗?

Fel*_*ing 8

计数器被声明为const,仍然可以更改!

counter在转换后的代码中有两个带名称的标识符:

  • 里面的参数 .counterincrement
  • 里面的变量 .countertest

他们是完全独立的!

参数永远不会"常量",始终可以为它们分配新值.它对传递给函数的内容没有影响,因为所有参数都是通过传递,即increment传递变量,然后将其赋值给参数. counter counter

我们可以通过在函数调用之前和之后记录变量的值来轻松验证这一点:

function increment(counter) {
 counter += 1; 
}

function test() {
    var counter = 1;
    console.log('value before', counter);
    increment(counter);
    console.log('value after', counter);
}

test();
Run Code Online (Sandbox Code Playgroud)

我只是试图理解,无论是Babel转换还是JavaScript规范都存在问题

没有.无论您是使用var还是const声明,它都可以指定counter.

我担心的是,如果我使用已编译的JavaScript,我可能会遇到未知的const相关错误.

不,情况并非如此.有什么const特别的?您无法为其分配新值并且它被阻止作用域.因此,让我们来看看Babel在违反这两个限制时所做的事情:

输入:

const foo = 21;
foo = 42;
Run Code Online (Sandbox Code Playgroud)

通天输出:

Babel拒绝使用错误来转换代码

SyntaxError: intput.js: "foo" is read-only
  1 | const foo = 42;
> 2 | foo = 21;
    | ^
  3 |
Run Code Online (Sandbox Code Playgroud)

输入:

{
  const foo = 21;
}
console.log(foo); // trying to access const outside of block
Run Code Online (Sandbox Code Playgroud)

通天输出:

"use strict";

{
  var _foo = 21;
}
console.log(foo); // trying to access const outside of block
Run Code Online (Sandbox Code Playgroud)

Babel重命名了块范围的变量.foo不存在(如预期的那样).

  • @FredStark不是一回事.引用本身仍然按值传递,即使对象也是如此.如果将对象传递给函数并重新赋值给参数,那么它也不会传播:`function test(foo){foo = {bar:'edit?' const in = {foo:'bar'}; 试验(在); // in仍然是{foo:'bar'}` (2认同)
  • @FredStark:是的,值*是*引用.但这与[pass*by*reference](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_reference)(也是/sf/ask/26139361/)不同之间传递按引用-VS-通过按值) (2认同)