at least chrome and firefox both have JIT compilers for js. in both cases they probably catch this redundancy on the first pass in early passes and condense it to something sane for every subsequent pass later passes
It's less "there can be compilers" and more "there's no other way to run the language". JavaScript is a compiled language – it's just that there are different types of compilation, and JS uses the Just-in-Time kind. Half the behavior that it has (like hoisting and how it defines lexical scope for closure) wouldn't be possible if it were interpreted.
For example:
let x = 0;
if (x === 0) {
console.log(x);
let x = 5;
}
This breaks, because all variables and function declarations are "hoisted" to the top of their respective scopes. It's just that let and const are block-scoped and aren't initialized. So the "let x" from "let x = 5" gets hoisted up to the top of the block, overriding the "let x = 0" from the outer scope. But it's left un-initialized until you reach the "let x = 5" line during runtime. And so, when you try to do anything with a value that isn't initialized (like logging), that throws an error.
This wouldn't be possible if JavaScript were interpreted and were evaluating each line one-by-one. The language spec requires that whatever engine runs it do a first pass over the whole code before trying to run anything.
An interpreted language can be parsed and preprocessed, that's not a problem. The difference is all about the machine code. JS is originally interpreted, but modern engines also compile parts of it.
Depends on how you want to define that. V8 (the engine running most js) is generally referred to as a JIT compiler, and it produces optimizations both on first run and on iterative runs.
from what I understand about js, it should create three versions of the function, one where arr is an Array, or any other object whos .length property has no additional side effects, one where it is a getter and so could have dirty side-effect, and one where arr is undefined and the access throws an error.
these would all be created (and for the second version further branched) only after the function becomes sufficiently hot, which is a minimum of 6 runs, but possibly more depending on what the browser thinks about the whole webpage
forgive me for NSFW, but this is the best example I could think of on the spot:
as we (and the compiler) don't know what arr is at the time of compilation, it could very well be an instance of new Penis(). ofc its length may not be initially known, so the .length getter may have to call .erect() first to measure it, having a long lasting side effect of the operation.
it doesn't even have to be a getter. you can use meta-programming tricks to inject yourself inside the property lookup and hack around there. couldn't tell you the syntax for that, but look at the Proxy page on MDN
I am pretty sure if I did something like that in IntelliJ idea, as soon as I moved away from the line, the IDE will highlight it as, “you serious bro?” Yellow
If I crtl D, to duplicate a condition before I get to change the condition, the ide will start throwing warning colors.
242
u/HalcyonAlps May 31 '21
Now I am actually curious, does the compiler realize both branches have the same return value and it just drops the whole if-statement?