# array comparison

jan 28 , 2013

Did you know that JavaScript can compare arrays using lexicographical ordering?

``````  [1, 2, 4] < [1, 2, 5]  // true
[1, 3, 4] < [1, 2, 5]  // false``````

Just don't expect trichotomy to hold.

``````  [1, 2, 3] === [1, 2, 3]   // false
[1, 2, 3] <   [1, 2, 3]   // false
[1, 2, 3] ==  [1, 2, 3]   // false
[1, 2, 3] >   [1, 2, 3]   // false``````

Oh, and just in case you're wondering, it knows it's messing with you.

``````  [1, 2, 3] <= [1, 2, 3]   // true
[1, 2, 3] >= [1, 2, 3]   // true``````

# undefined props on numbers

dec 28 , 2012
``````    function getBounds(node) {
var n = node || 0;
return { width: n.width, height: n.height };
}``````

If you call `getBounds()` with null, you'll get back `{ width: undefined, height: undefined }` because in JS, numbers have properties (inherited from Number), and using an undefined property doesn't throw, it just returns undefined. `null` and `undefined` are propertyless. Definitely not what I expected in a quick reading of code like this.

oct 10 , 2012
``````    parseFloat( 'Infinity' ) // returns Infinity
Number( 'Infinity' ) // returns Infinity
parseInt( 'Infinity' ) // returns NaN, of course. With any radix passed as well.``````

sept 19 , 2012

In JS you can represent numbers in hexadecimal, right?

``````
var hex = 0xFF55;
``````

You can also perform shift operations, right? Left shift is equivalent to a multiplication...

``````    var hex = 0xFF55 << 8;  // Shift 8 bits = add 0x00 at the end.

But from a certain point, this produces negative numbers

``````    // Before 0x800000 it's ok

// After 0x800000 it's not ok
alert((0x888888 << 8).toString(16)); // -77777800, WTF?

// The only way to remain positive is to multiply instead of shifting

Thanks JS for making left shift different than a multiplication!

I do have an explanation!

ES5 states that the left-shift operator is a signed shift on 32 bits represented by two's complement which means that the highest order bit defines the sign.

7 in hexa = 0111 in binary (every number below 7 starts with 0) 8 in hexa = 1000 in binary (every number above 8 starts with 1)

So in binary:

(0x777777 << 8) in hexa = 0111 0111 0111 0111 0111 0111 0111 0000 0000 in binary (the 32nd bit is still 0)

(0x888888 << 8) in hexa = 1000 1000 1000 1000 1000 1000 0000 0000 in binary (the 32nd bit becomes 1 => negative)

As for why multiplying 0x888888 0x100 yields a different result, both operands to the operator are numeric, so each is casted to a IEEE 64-bit double, then multiplied, which means this is what is really happening:

``    0x888888 * 0x100 === 8947848.0 * 256.0 === 2290649088.0``

When this is converted into a string with base 16, what you get is 88888800.

# Slashes!

aug 11 , 2012

What should the following JS yield?

``````
n = 1
/1*"\/\//.test(n + '"//')
``````

Should it be `true`? (It is `NaN`.)

Using semicolons, on the other hand, makes it behave like you'd expect:

``````
n = 1;
/1*"\/\//.test(n + '"//');
``````

(Returns `true`.)

The fun around this WTFJS comes from trying to understand how this should be parsed, so please have fun experimenting with the snippet of code.

When you're done understanding the different levels on which it plays, read on.

The trick revolves around the different cases in which the slash character has meaning. There are three cases: comments, regular expressions, and division, all of which are meant to be on display here.

In the first, semicolon-free snippet, the first slash on the second line is a division. We divide 1 by 1, multiply it by a long string, and after that there is a comment.

In the second snippet, with semicolons, the second line is a regex, tested against the global variable in the first line, transmuted to a string via concatenation.

An interesting variation that shows what happens more clearly is the following:

``````
n = 1
/1?":n\/\//.test(n + '":n//')
``````

That returns `":n///.test(n + '"`. It gives the trick away. (It uses the ternary operator `?:`, if you're wondering.)

Obviously, if you really want your friends to have a headache, give them this version:

``````
n = 0
/0?":n\/\//.test(n + '":n//')
``````

That returns `undefined`, which is even more obscure than the `NaN` that we got in the first snippet. Yes, `0/0` is `NaN`, which is falsy.