Counter is declared const, still it can be changed!
There are two identifiers with name counter
in the transpiled code:
- The parameter
counter
inside increment
.
- The variable
counter
inside test
.
They are completely independent!
Parameters are never "constant", they can always be assigned a new value. It has no impact on what you passed to the function, since all arguments are passed by value, i.e. increment
is passed the value of the variable counter
which is then assigned to the parameter counter
.
We can easily verify this by logging the value of the variable before and after the function call:
function increment(counter) {
counter += 1;
}
function test() {
var counter = 1;
console.log('value before', counter);
increment(counter);
console.log('value after', counter);
}
test();
I'm just trying to understand, whether it is a problem with Babel transpilation or with JavaScript specification
With neither. It works exactly has specified, no matter whether you are using var
or const
to declare counter
.
My concern is, if I use transpiled JavaScript, I may encounter unknown const related bug.
No, that won't be the case. What makes const
special? That you cannot assign a new value to it and that it is blocked scoped. So lets have a look what Babel does when you are violating these two constraints:
Input:
const foo = 21;
foo = 42;
Babel output:
Babel refuses to transpile the code with the error
SyntaxError: intput.js: "foo" is read-only
1 | const foo = 42;
> 2 | foo = 21;
| ^
3 |
Input:
{
const foo = 21;
}
console.log(foo); // trying to access const outside of block
Babel output:
"use strict";
{
var _foo = 21;
}
console.log(foo); // trying to access const outside of block
Babel renamed the block-scoped variable. foo
doesn't exist (as expected).