I try to check whether a "variable" in es6 is constant:
const a = 1;
function test() {
try {
a = 2;// throws an error
} catch (error) {
console.log(error)
}
}
test();
But when I use eval() function ,It doesn't throws an error.
const a = 1;
function test() {
try {
eval("a = 2;")// not throws an error
} catch (error) {
console.log(error)
}
}
test();
And I make the constant local, the function eval does throw an error as expected.
function test() {
try {
const a = 1;
eval("a = 2;")//throws an error
} catch (error) {
console.log(error)
}
}
test();
And when I use function eval() that cause it doesn't throw an error as expectd. What the functoin eval() have done here ? I run it in Node v6.2.2
const a = 1;
function test() {
try {
eval("");
a = 2; // will not throw an error
} catch (e) {
console.log(e)
}
}
test();
More interesting, I enclose eval() with if (false),it will not throw an error either.
const a = 1;
function test() {
try {
if (false) {
eval("");
}
a = 2; // will not throw an error
} catch (e) {
console.log(e)
}
}
test();
Anyone can tell me the reason?
Is this a bug in JavaScript?
And how can I catch the global constant variable changed error?
The fact that eval("a = 2;")
in your code doesn't throw a TypeError
looks like a bug in V8 (the JavaScript engine in Chrome).
const
creates a strict binding via the spec operation CreateImmutableBinding (see Step 16.b.i.1 of GlobalDeclarationInstantiation).
When assigning to an immutable binding (a = 2
), a TypeError
is meant to be thrown by SetMutableBinding
if either 1. The code is in strict mode, or 2. The binding is a strict binding.
So in your code not using eval
, you're running in loose mode, but it throws a TypeError
anyway because the binding is strict. But V8 doesn't seem to be checking whether the binding is strict when you do eval("a = 2;")
. (SpiderMonkey [Firefox] does, and throws the TypeError
; as does JScript in IE11. I don't have Edge handy to check Chakra.)
You can make V8 throw the error by making the code in the eval
strict:
const a = 1;
function test() {
try {
eval("'use strict'; a = 2;");
}
catch (error) {
console.log(error);
}
}
test();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With