
A tour of V8: object representation (2013) - tambourine_man
http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation
======
zbjornson
> if you assign to an index that's way past the end of your the elements
> array, V8 may downgrade the elements to dictionary mode... avoid copying
> from the back

Sublime I think still has the snippet for "optimized for loop" that runs in
reverse. I have never seen that improve performance, and I didn't know that it
could actually be harmful if used to initialize an array.

------
ryanlm
Yesterday I had to store integers as keys in a map. It's good to learn today
that they are implicitly converted to strings. Yes I could have used an array,
but that would of required me to know the max index I would suppose. Maybe in
JavaScript I insert into the array at any index, but that doesn't seem usual
to me, coming from a C background I'd allocate the max index + 1.

~~~
chrisseaton
I'm not a JavaScript expert but I believe most serious JavaScript
implementations can represent sparse arrays, or arrays with holes in the range
of indices, for this reason.

~~~
BillinghamJ
Vaguely relevant/example: [http://imgur.com/7Bf3hLZ](http://imgur.com/7Bf3hLZ)

------
bryanrasmussen
var a = new Array();

a[-0] = "foo";

console.log(a.length);

console.log(a[-0]);

and people complain it's not fun.

On edit - should probably have done this instead

var a = new Array();

a[-0] = "foo";

a[-1] = "foo+";

console.log(a.length);

for(var b = 0; b < a.length; b++){

    
    
      console.log(a[b]);
    
    }

~~~
TAForObvReasons
Both parts have very clear and unsurprising explanations if you understand how
IEEE 754 doubles work (same type as C double). For example, section 15.4 of
ES5:

[http://ecma-international.org/ecma-262/5.1/#sec-15.4](http://ecma-
international.org/ecma-262/5.1/#sec-15.4)

> 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
> 232−1.

.

-1 is the easier case to understand: ToUint32(-1) is 2^32 - 1 and ToString(ToUint32(-1)) is "4294967295", which is very clearly not -1.

Needless to say, the C equivalent is an out-of-bounds dereference.

.

While -0 is technically a different value from 0 (it's called negative zero in
IEEE 754), the ToUint32 operation specifically carves out a case:

[http://ecma-international.org/ecma-262/5.1/#sec-9.6](http://ecma-
international.org/ecma-262/5.1/#sec-9.6)

> If number is NaN, +0, −0, +∞, or −∞, return +0.

The "same thing" happens in C:

A) The literal `-0` is interpreted as an integer. The actual value it uses is
zero:

    
    
        char ** foo = (char **)malloc(3 * sizeof(char *));
        foo[0] = foo[1] = foo[2] = "foo";
        foo[-0]="bar"; /* this sets foo[0] since the compiler treats -0 as the unary negation of the integer 0 and integers have no signed zero */
        printf("%d|%s|%s|%s\n", -0, foo[0], foo[1], foo[2]); /* "0|bar|foo|foo" since the -0 is understood by the compiler to be the actual value 0 */
    

B) Since JS interprets `-0` as an IEEE754 double, the value can be recreated
by going through negative infinity:

    
    
        double ninf = (-1.0/0.0); /* should be -Infinity */
        printf("%g\n", ninf); /* "-inf" just to be sure */
        double nzero = (1.0 / ninf); /* should be IEEE 754 negative zero */
        printf("%g %d %zu\n", nzero, (int)nzero, (size_t)nzero); /* "-0 0 0" -0 behaves like 0 when casted to integer types */
    

.

The arguably surprising part is that JS doesn't have integer literals, but
that isn't surprising when you think about the fact that JS only has one
number type which maps to IEEE 754 double.

~~~
bryanrasmussen
I didn't say it was unclear or surprising, it's very obvious since an array is
an object with the special length property.

this is also obvious:

var a = new Array();

a["hello world"] = "foo";

console.log(a.length);

console.log(a["hello world"]);

Now, I don't think anyone would ever do this, but it does seem to me show
weirdness in the conceptual model.

although I guess you could have someone on accident setting the value of an
item in array and using a key that was NaN, example

var a = new Array();

var f = f + 3;

a[f] = "foo";

console.log(a.length);

console.log(a[f]);

I guess though it's weirdness that is easy to understand and doubtful to ever
come around to bite you.

------
drivingmenuts
The more I read about the internals of Javascript, the more terrified I get.
It seems to be constructed haphazardly and held together with lots of duct
tape.

~~~
titzer
You have no idea.

/v8 hacker

~~~
adam77
i got a taste after reading this...

[https://ia601208.us.archive.org/16/items/vmss16/titzer.pdf](https://ia601208.us.archive.org/16/items/vmss16/titzer.pdf)

