Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Further expanding on previous answers...</p> <p>From a general compilers perspective and disregarding VM-specific optimizations:</p> <p>First, we go through the lexical analysis phase where we tokenize the code.</p> <p>By way of example, the following tokens may be produced:</p> <pre><code>[]: ARRAY_INIT [1]: ARRAY_INIT (NUMBER) [1, foo]: ARRAY_INIT (NUMBER, IDENTIFIER) new Array: NEW, IDENTIFIER new Array(): NEW, IDENTIFIER, CALL new Array(5): NEW, IDENTIFIER, CALL (NUMBER) new Array(5,4): NEW, IDENTIFIER, CALL (NUMBER, NUMBER) new Array(5, foo): NEW, IDENTIFIER, CALL (NUMBER, IDENTIFIER) </code></pre> <p>Hopefully this should provide you a sufficient visualization so you can understand how much more (or less) processing is required.</p> <ol> <li><p>Based on the above tokens, we know as a fact ARRAY_INIT will always produce an array. We therefore simply create an array and populate it. As far as ambiguity, the lexical analysis stage has already distinguished ARRAY_INIT from an object property accessor (e.g. <code>obj[foo]</code>) or brackets inside strings/regex literals (e.g. "foo[]bar" or /[]/)</p></li> <li><p>This is miniscule, but we also have more tokens with <code>new Array</code>. Furthermore, it's not entirely clear yet that we simply want to create an array. We see the "new" token, but "new" what? We then see the IDENTIFIER token which signifies we want a new "Array," but JavaScript VM's generally do not distinguish an IDENTIFIER token and tokens for "native global objects." Therefore...</p></li> <li><p>We have to look up the scope chain each time we encounter an IDENTIFIER token. Javascript VMs contain an "Activation object" for each execution context which may contain the "arguments" object, locally defined variables, etc. If we cannot find it in the Activation object, we begin looking up the scope chain until we reach the global scope. If nothing is found, we throw a <code>ReferenceError</code>.</p></li> <li><p>Once we've located the variable declaration, we invoke the constructor. <code>new Array</code> is an implicit function call, and the rule of thumb is that function calls are slower during execution (hence why static C/C++ compilers allow "function inlining" - which JS JIT engines such as SpiderMonkey have to do on-the-fly)</p></li> <li><p>The <code>Array</code> constructor is overloaded. The Array constructor is implemented as native code so it provides some performance enhancements, but it still needs to check for arguments length and act accordingly. Moreover, in the event only one argument is supplied, we need to further check the type of the argument. new Array("foo") produces ["foo"] where as new Array(1) produces [undefined]</p></li> </ol> <p>So to simplify it all: with array literals, the VM knows we want an array; with <code>new Array</code>, the VM needs to use extra CPU cycles to figure out what <code>new Array</code> <em>actually</em> does.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload