Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does JavaScript [] really work?

I'm writing a JavaScript interpreter for extremely resource-constrained embedded devices (http://www.espruino.com), and every time I think I have implemented some bit of JavaScript correctly I realise I am wrong.

My question now is about []. How would you implement one of the most basic bits of JavaScript correctly?

I've looked through the JavaScript spec and maybe I haven't found the right bit, but I can't find a useful answer.

I had previously assumed that you effectively had two 'maps' - one for integers, and one for strings. And the array length was the value of the highest integer plus one. However this seems wrong, according to jsconsole on chrome:

var a = [];
a[5] = 42;
a["5"]; // 42
a.length; // 6

but also:

var a = [];
a["5"] = 42;
a[5]; // 42
a.length; // 6

So... great - everything is converted into a string, and the highest valued string that represents an integer is used (plus one) to get the length? Wrong.

var a = [];
a["05"] = 42;
a.length; // 0

"05" is a valid integer - even in Octal. So why does it not affect the length?

Do you have to convert the string to an integer, and then check that when converted back to a string, it matches?

Does anyone have a reference to the exact algorithm used to store and get items in an array or object? It seems like it should be very simple, but it looks like it actually isn't!

like image 556
Gordon Williams Avatar asked Apr 11 '13 19:04

Gordon Williams


People also ask

How does JavaScript code work?

The source code is passed through a program called a compiler, which translates it into bytecode that the machine understands and can execute. In contrast, JavaScript has no compilation step. Instead, an interpreter in the browser reads over the JavaScript code, interprets each line, and runs it.

How do JavaScript engines work under the hood?

It all starts with getting JavaScript code from the network. V8 parses the source code and turns it into an Abstract Syntax Tree (AST). Based on that AST, the Ignition interpreter can start to do its thing and produce bytecode. At that point, the engine starts running the code and collecting type feedback.

How does JavaScript code is executed in browser?

To execute JavaScript in a browser you have two options — either put it inside a script element anywhere inside an HTML document, or put it inside an external JavaScript file (with a . js extension) and then reference that file inside the HTML document using an empty script element with a src attribute.

How does JavaScript V8 engine work?

The V8 engine uses the Ignition interpreter, which takes in the Abstract Syntax Tree as the input and gives the byte code as the output, which further proceeds to the execution phase. When the code is being interpreted, the compiler tries to talk with the interpreter to optimize the code.


2 Answers

As the specs said, and was noted by others:

"A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32-1."

That's explain why in your scenario "5" is considered an array index and "05" is not:

console.log("5" === String("5" >>> 0));
// true, "5" is equal to "5", so it's an index

console.log("05" === String("05" >>> 0));
// false, "05" is not equal to "5", so it's not an index

Note: the Zero-fill right shift is the shortest way in JS to have a substitute of ToUint32, shifting a number by zero.

like image 78
ZER0 Avatar answered Sep 27 '22 23:09

ZER0


See MDN

It's possible to quote the JavaScript array indexes as well (e.g., years["2"] instead of years[2]), although it's not necessary. The 2 in years[2] eventually gets coerced into a string by the JavaScript engine, anyway, through an implicit toString conversion. It is for this reason that "2" and "02" would refer to two different slots on the years object and the following example logs true:

console.log(years["2"] != years["02"]);

So with a["5"] you are accessing the array while a["05"] sets a property on the array object.

like image 25
laktak Avatar answered Sep 28 '22 01:09

laktak