The Alert to Life, the Universe and Everything, Part 3 – There are no strings on me.

Hello again. In the last two posts we’ve been looking at this amazing piece of code and breaking it down, bit by bit:

[][(__=”+!!(_=+[]))[_$=-~-~-~_]+($$=”+{})[$=-~_]+($_=”+!_)[$]+$_[_]][$$[-~($+_$)]+$$[$]+(”+$/_)[$]+__[_$]+$_[_]+$_[$]+$_[$+$]+$$[-~($+_$)]+$_[_]+$$[$]+$_[$]](__[$]+__[$+$]+$_[_$]+$_[$]+$_[_]+”(“+((($<<($<<$)^$)<<($<<$)^$)<<$)+”)”)()

This is valid JavaScript code that provides an alert with the number 42 in it. Now, those looking at this for the first time will have heart palpitations and scream to the high heavens “What the f[CENSORED]k is this sorcery?” But, if you’ve been following my blog for some time now and read through my last post in particular, you’ll know that we’ve been decoding various aspects of code, piece by piece. Last post, were focused our efforts on numbers. As a result, our crazy code above was converted to the following:

[][(__=”+!!(_=0))[_$=3]+($$=”+{})[$=1]+($_=”+!_)[1]+$_[0]][$$[5]+$$[1]+(”+Infinity)[1]+__[3]+$_[0]+$_[1]+$_[2]+$$[5]+$_[0]+$$[1]+$_[1]](__[1]+__[2]+$_[3]+$_[1]+$_[0]+”(“+42+”)”)()

which albeit, is a little more legible, doesn’t give the full gist of what’s being executed. So, let’s decode it further. We tackled numbers in the previous post. Today, we’re going to look at strings.

Looking at our semi-digested code here, we can spot a number of references to empty strings:

  • (__=”+!!(_=0))
  • ($$=”+{})
  • ($_=”+!_)
  • (”+Infinity)

And two references to non-empty strings, “(” and “)”. Let’s take a look at the four code examples above and see what they’re all about.

(__=”+!!(_=0)), self-encapsulated variable assignments so that the values can be used straight away, we already determined the value of _ in the previous post as zero. Now, we have the double-not operator operating on zero, which you may remember from my previous post coerces the operand (the zero) to its equivalent Boolean. As zero is a falsy value, !!0 is coerced to the Boolean false. So far, so good. Next to the newly determined false we have an empty string and a concatenation operator. This empty string and the concatenation operator serve one purpose and one purpose only – to coerce the object they’d act upon to a string representation of it. In the case of false, it gets coerced to the string “false”, the value for __. Let’s put it aside for now, and move onto the next piece of code.

($$=”+{}), also self-encapsulated for immediate use. But this time we have the empty string and concatenation operator dynamic duo acting upon an empty object. Objects are weird things, and so, accordingly, the result is about as weird; the string result is not “object”, but rather “[object Object]”. I currently do not have the reasons for why this is at the moment, but I promise I’ll have a look and let you readers know in a future post. Just check it out for yourself. So that’s the value of $$ sorted. We’ll put that aside as well, age move on.

($_=”+!_), once again, self-encapsulated for immediate use of the value. This is similar to our first piece of code, save for a single-not operator acting on the zero value held by the _ variable. As a result !0 coerces the zero to a Boolean first, false, before applying the not, which results in $_ equalling ”+true, which is again coerced to “true”, the string equivalent of the Boolean true. Moving on to our final piece of code.

(”+Infinity), self-encapsulated (sensing a pattern?)… But this time, no assignment, so this is a one-off. This is a simple conversion of the object name to a string, rather much like true and false are. So, long story short, this code is equivalent to “Infinity”, the string.

So, with our newly discovered strings, and hoisting the variables to the top, let’s see what were get when we plug those in:

[][‘false'[3]+(‘[object Object]’)[1]+’true'[1]+’true'[0]][‘[object Object]'[5]+'[object Object]'[1]+’Infinity'[1]+’false'[3]+’true'[0]+’true'[1]+’true'[2]+'[object Object]'[5]+’true'[0]+'[object Object]'[1]+’true'[1]](‘false'[1]+’false'[2]+’true'[3]+’true'[1]+’true'[0]+”(“+42+”)”)()
This makes it somewhat more legible, but a bit of a mouthful, as well as a bit repetitive in places. We still have these array references everywhere… I promised in my previous post I would reveal the mystery of these array references, and here it is – Strings, in the eyes of JavaScript, are arrays of single character strings. For example, in the string “string”, “string”[0] is the first character “s”, “string”[1] is the second character “t”, and so on. The only exception is where you try to get the nth character of an empty string, like ”[0], which logically comes back as undefined.

Strings, in the eyes of JavaScript, are arrays of single character strings.

Using this knowledge, if you plug and chug this into our updated code we get the following:

[][‘s’+’o’+’r’+’t’][‘c’+’o’+’n’+’s’+’t’+’r’+’u’+’c’+’t’+’o’+’r’](‘a’+’l’+’e’+’r’+’t’+”(“+42+”)”)()

which when we apply all the concatenation operators gives us:

[][‘sort’][‘constructor’](‘alert(42)’)()

Very legible, but the syntax is probably unfamiliar to you, But, if you were to run this you would still get your alert with 42; why is that?

Let’s look from left to right here.

You have an empty array [], followed by an array reference of “sort”. This is actually referring to the array object’s native method of sort. If you ran:

[2,1,3][“sort”]()

You would get the same result as if you had run:

[2,1,3].sort()

As non-alphanumeric JavaScript is unable to provide a way that would allow you to access methods or properties in dot format like x.y or x.y(), JavaScript has these alternative forms, x[“y”] and x[“y”]() available for you to use.

But note that a) we have an empty array in use, and b) we have a second chained array reference. Why is that? I’ll answer (b) first: x[“y”][“z”] is the same as x.y.z, so the more and more array references is equivalent to more and more dot references until you get to the property or method you are trying to access. In this case, you’re accessing the constructor property of the empty array’s sort method.

But here’s the thing, [][‘sort’][‘constructor’] gives rise to JavaScript’s native Function method on the window object:

function Function() { [native code] }

In fact, if you were to execute:

window.Function(“alert(42)”)()

You’d be doing the exact same thing as:

[][‘sort’][‘constructor’](‘alert(42)’)()

The Function method then takes the first parameter which is basically what we want it to do, and then the () ensures the execution.

You can conclude this is an alternative form of getting a JavaScript statement to execute. As to (a), the empty array is for simplicity.

So, given all this, let’s look into some other crazy crap that could be achieved this way. This concludes Part 3. There won’t be Part 4, but I promise to make the next few posts just as interesting. Until then, stay quirky!

Advertisements

The Alert to Life, the Universe and Everything, Part 2 – “Don’t Lose my Number”

So my previous post had this gorgeous monstrosity:

[][(__=”+!!(_=+[]))[_$=-~-~-~_]+($$=”+{})[$=-~_]+($_=”+!_)[$]+$_[_]][$$[-~($+_$)]+$$[$]+(”+$/_)[$]+__[_$]+$_[_]+$_[$]+$_[$+$]+$$[-~($+_$)]+$_[_]+$$[$]+$_[$]](__[$]+__[$+$]+$_[_$]+$_[$]+$_[_]+”(“+((($<<($<<$)^$)<<($<<$)^$)<<$)+”)”)()

This code results in an alert with the number 42 in it…

So, how do we get from that code to 42? Well, as I said in my previous post, a lot of it deals with loose typing and some pretty cool math wizardry. I’m going to focus on the numerical side of things in this post so that we can see how we’re getting numbers when there are no numbers in sight.

Before I begin, I also mentioned in my previous post that some awesome variable naming conventions were being used. Take a look at the following instances that are present in the code:

  • _ (single underscore)
  • __ (double underscore)
  • $ (single dollar)
  • $$ (double dollar)
  • $_ (dollar underscore)
  • _$ (underscore dollar)

JavaScript accepts all these as valid variable names. If I were to restrict my definition to the ASCII subset of what’s valid, a valid JavaScript variable name can consist of any combination of numbers, lowercase and uppercase Latin letters, underscore and dollar sign, provided it doesn’t start with a number. The best full definition for valid JavaScript variable names can be found here.

So, because we have variable names in the code, the equal signs next to them are used for assignment.

So, now that we’ve established that, let’s focus on the numbers.

Firstly, we have the following snippet:

_=+[]

What’s the go with this, I hear you ask? Here, we’re assigning the value of _ to 0. To explain this, we need to establish what we already know about falsy values. Falsy values are what can be coerced to false when acted on by a Boolean operator. To determine whether a value or object is falsy, you apply the logical double-not operator on it and view the result. If the result is false then your original value is falsy. 0 is a falsy value, an empty string “” is falsy, and so is an empty array []. Applying the unary positive operator + on a falsy value coerces it to zero.

So _=+[] is identical to _=0.

You may have noticed this variable assignment its nested within another variable assignment:

(__=”+!!(_=+[]))

This is valid JavaScript. Granted, it’s not pretty, but it’s valid nonetheless. The purpose of doing this is so that the variable can be used at the time the variable is being defined. In this instance, __ is defined as an empty string concatenated to the double-not Boolean of 0. If you’ve read previous posts of my blog, you’d know that the double-not operator coerces the 0 to false, the Boolean value, and the empty string with the concatenation operator coerced that, in turn, to “false”, the string. But we’ll focus on the string parts in my next post.

The next variable assignment of interest is the following:

_$=-~-~-~_

Minus tilde, minus tilde, minus tilde… So it’s repeated three times, but what does that mean? Let’s look at the following:

-~0

We knew the underscore variable in our example was zero, so I’ve rendered it out as such. The tilde operator takes the number to the right of it, and performs the following algorithm on it -(N+1), then spurs back the result. In this example, ~0 is equal to -(0+1) = -1. Seems like a strange thing for an operator to do, but it works. So we have -1, but we also have the additional unary negative operator in front of it, do this coerces to -(-1) or 1. So technically -~N is the same as N+1.

So, that would mean that _$=-~-~-~_ is the same as _$=0+1+1+1 which means we’ve just written the equivalent of _$=3. Similarly, the $=-~_ reference in ($$=”+{})[$=-~_] is equivalent to $=1.

Next, we have the encapsulated statement in $$[-~($+_$)]. $+_$ based from the previous paragraphs is equivalent to 1 ($) plus 3 (_$) which is 4, but with the -~ operators, this raises it to 5. So this statement is the same as $[5].

Following this section there’s third little nugget…

$/_ … But if you do your substitutions that works out to be 1/0, which is mathematically infinite… Well, luckily, JavaScript has the Infinity value… We’ll address how Infinity comes into play in this code in the next post…

And the $+$ reference is simply 1+1 which is equal to 2.

Lastly, we have this “centrepiece” statement:

((($<<($<<$)^$)<<($<<$)^$)<<$)

This makes use of the number 1 (the value of $) over and over again… But why?

Here’s why, let’s substitute $ for one and see what we have.

(((1<<(1<<1)^1)<<(1<<1)^1)<<1)

Two operators here at work, the left-bitwise shift operator (<<) and the bitwise XOR operator (^).

Quick lesson on how these two work:

The bitwise left shift operator (we’ll call it the BLSO from here on) takes the number and shifts all bits one bit to the left. With each shift, you’re essentially doubling the number. The general formula is that X<<Y is equivalent to doubling X, Y times. So 5<<1 = 10, 5<<2 = 20 and so on. Bear in mind this works specifically for the integers party of your numbers only. If you executed 9.6<<1 your answer will be 18 not 19.2.

1<<1 is therefore 2 so let’s substitute it back in:

(((1<<2^1)<<2^1)<<1)

Note the section in bold: (1<<2^1), the BLSO takes precedence over the XOR operator, so we run it through again:

(((4^1)<<2^1)<<1)

So the XOR operator, what happens here? The XOR operator in this case compares the numbers bit by bit, and returns true if and only if the bit in both numbers are not identical, otherwise. 1 and 0? Return 1. 0 and 1? Return 1. 1 and 1 or 0 and 0? Return 0. So in our first case, 4^1, i.e. 4 XOR 1 I’d worked out as:

4: 100

1: 001

XOR: 101 = 5

This is a rather clever way of adding 1 to any multiple of 2 as any multiple of 2 will naturally have that 1’s bit (the one at the very right of a positive binary number) set to zero. So, 1<<1^1 is 3, 2<<3^1 is 17 and so on.

So let’s plug it and chug it over and over, using what we’ve learned and see what we get.

(((4^1)<<2^1)<<1)4^1 = 5

((5<<2^1)<<1) …5<<2 is 5×2×2 = 20

((20^1)<<1) …20^1 = 21

21<<1 …21<<1 = 42

We have our magical 42 popping up… So what’s the go with the rest of the code? This, my dear readers, is the code for the JavaScript alert, but we will get to that within the next few posts. Before I go, let’s take another look at that original code:

[][(__=”+!!(_=+[]))[_$=-~-~-~_]+($$=”+{})[$=-~_]+($_=”+!_)[$]+$_[_]][$$[-~($+_$)]+$$[$]+(”+$/_)[$]+__[_$]+$_[_]+$_[$]+$_[$+$]+$$[-~($+_$)]+$_[_]+$$[$]+$_[$]](__[$]+__[$+$]+$_[_$]+$_[$]+$_[_]+”(“+((($<<($<<$)^$)<<($<<$)^$)<<$)+”)”)()

Now let’s take a look at that same code with all the numbers rendered out:

[][(__=”+!!(_=0))[_$=3]+($$=”+{})[$=1]+($_=”+!_)[1]+$_[0]][$$[5]+$$[1]+(”+Infinity)[1]+__[3]+$_[0]+$_[1]+$_[2]+$$[5]+$_[0]+$$[1]+$_[1]](__[1]+__[2]+$_[3]+$_[1]+$_[0]+”(“+42+”)”)()

A little more recognizable… But you’ve noticed we have a lot of array references here, yet no arrays have been created?

Well, they have, but not how you’d expect… I’ll tell you more in the next post, also entitled “I’ve got no strings on me”. Stay tuned!

The Alert to Life, the Universe and Everything… Part 1

I’m going to hit you with some supposed gobbledygook here…

[][(__=”+!!(_=+[]))[_$=-~-~-~_]+($$=”+{})[$=-~_]+($_=”+!_)[$]+$_[_]][$$[-~($+_$)]+$$[$]+(”+$/_)[$]+__[_$]+$_[_]+$_[$]+$_[$+$]+$$[-~($+_$)]+$_[_]+$$[$]+$_[$]](__[$]+__[$+$]+$_[_$]+$_[$]+$_[_]+”(“+((($<<($<<$)^$)<<($<<$)^$)<<$)+”)”)()

Now, copy and paste it into your JavaScript console in your browser…

With me so far? Okay, now that you’ve pasted that, hit the Enter key on your keyboard.

You should get something similar to this:


An alert with 42 in it…

I showed this to a friend of mine who said in response “This is nuts!”

This was an entry of mine for a coding competition for displaying the number 42 on the most creative way thinkable.
This takes advantage of a lot of weird quirks of JavaScript like loose typing, alternative variable naming conventions, primitives and some really awesome bit mathematics. I’m going to go though these step by step over the next few posts.

Ready to be absolutely but happily mindf[CENSORED]ked? Okay, strap yourselves in, this is going to be a hell of a ride…

Stay tuned for Part 2, Don’t Lose My Number…

#BecauseJavaScript Part 3 – Undefined makes a comeback…


Once again, I’m having to explain why JavaScript behaves a certain way… Programmers other than myself are baying for Brendan Eich’s blood because they don’t understand what is happening and just chalk it up to #BecauseJavaScript…

Let’s take a look at an example here:


Here, Vishal Gupta, not content with the result he’s been given by JavaScript has taken to Twitter to complain about it…

Dude, chill, have some guacamole and sit back and let Uncle Eliseo take you on a guided tour on why JavaScript gave you “3” as to the answer to life, the universe and everything… And not “42”.

Let’s take a look at the syntax:

‘Befundefinedit’.indexOf()

Result: 3

So, we have a string ‘Befundefinedit’, being actioned by the indexOf method. The only exception is that there’s no string value being passed as a parameter… You could say that parameter is undefined…

And you would be right, but at the sane time, the parameter is also undefined. Yes, just because no value has been passed through doesn’t mean JavaScript will accept that at face value (no pun intended). JavaScript will consider what type of value is expected and coerce whatever has been passed through, even if the parameter passed is undefined. If it’s undefined, then JavaScript will be all like “Okay, buddy, you wanna go with an undefined value? We’ll try to work with you…” and then default value types and loose typing take over…

So in Vishal’s example, undefined is technically passed through the indexOf method, indexOf expects the parameter to be a string, so loose typing coerces undefined to become ‘undefined’ and uses that as its search term. In the string ‘Befundefinedit’ the search term ‘undefined’ appears at index 3 (remembering that strings, just like all arrays in JavaScript, are zero-based), and so it returns 3 as the final answer…

So, what’s our take away here? If a JavaScript method expects a parameter to be a specific type, a value of any other type that is passed to that method will be coerced to the expected type before execution. I’ll repeat this again, in quotes, because I can’t stress it enough…

If a JavaScript method expects a parameter to be a specific type, a value of any other type that is passed to that method will be coerced to the expected type before execution.

Another take away is that if a parameter is undefined, JavaScript will take you literally and go with undefined.

That being said, let’s go with a few more examples:

‘This is not a null string’.indexOf(null)

This returns 14. You guessed it, null just got coerced to a string and became ‘null’. The rest is pretty straight forward, as ‘null’ appears at index 14 of the string. I have to admit, I did have a little chuckle when I discovered this some time back.

‘1234567890’.indexOf(0)

This returns 9, as 0 after being coerced to ‘0’ is found at index 9 of the string.

x=(1!=0); ‘misconstrued as falsehoods’.indexOf(x)

This is a tricky one… I’ve predefined x with a Boolean value. We can see that I’ve cleverly put both ‘true’ and ‘false’ within the string. Which index will it return, 7 or 16? Keep your answer to yourself for just a little longer while we examine this one…

!= as everyone knows is the inequality operator in JavaScript. So, is 1 not equal to 0? Damn straight, so it’s true, so true is the value assigned to x. As x is passed to the indexOf method, it gets coerced to ‘true’ and the above syntax returns… 7. Hands up all those that got it right…

So what if we change it up a little?

x=(1!=0); ‘misconstrued as falsehoods’.indexOf(!x)

The only difference here is that we’ve passed through x which has also been acted upon by the negation operator, !. As a result, !x is passed, which means false its passed, which is coerced to ‘false’ which results in 16 being returned in this instance.

So, where do we go from here…? Just a reminder that if JavaScript gives you an answer that is perplexing or in Vishal’s case, so detrimental to his well-being that he took to Twitter to bemoan the fact that this syntax was the bane of his existence; take a step back and look at how the syntax you’re using works, what it expects, and how loose typing may have come into play.

I have a doozy of a next post that will make your freaking heads spin coming soon. In the mean time, have a great day!

#BecauseJavaScript Part 2 – String Comparisons

Welcome back!

I delved into Twitter again and found this little tweet by Nico Castro. This is a quick one, but it does need a fair bit of explanation to clarify things.

So what’s going on here? Why is the small ‘a’ greater than capital ‘Z’, but at the same time has capital ‘A’ not greater than capital ‘Z’?

Nico is on the right track, ASCII has a lot to do with it, but it’s a teeny tiny bit more complex than that… Let’s take another look at those two statements:

"a" > "Z" // true

"A" > "Z" // false

So, as I said, there is some focus on the ASCII component of the strings that comes into play.

Let’s replace the strings with their ASCII numeric equivalents. Once we do, we see something that instantly clicks:

97 > 90 // "a" > "Z" == true!

65 > 90 // "A" > "Z" == false!

Ta-dah! JavaScript has this unique way with comparing strings when it comes to the greater-than and lesser-than operators. In comparing strings, JavaScript treats them as arrays comprised of single character elements, so in the first example, JavaScript is really comparing [“a”] against [“Z”], JavaScript then compares both arrays, index by index.

Here are three more examples…

"ab" > "ac" // false
"ab" > "a" // true
"ate" > "are" // true

The first example gets converted to their respective arrays: [“a”,”b”] and [“a”,”c”], and then runs through the conversions to the numeric equivalents: [97,98] and [97, 99]. From there, JavaScript will compare these two arrays index by index until it finds a pair that satisfies the comparison operator in question. If it cannot find a pair of elements satisfying the comparison false is returned, otherwise it will return true. If, however, we find a pair of elements that does satisfy the comparison, it returns true and breaks out of the check. So in this first example, the zeroth element for both arrays is 97. 97 isn’t greater than 97, so it then tests out the first elements of, 98 against 99, 98 is not greater than 99, and thus because we’ve reached the end of both arrays without anything satisfying the comparison, it returns false.

Second example is slightly trickier. We have a two character-long string compared against a single character. What happens there?

If you were to type “a”[0] into a JavaScript console, you’d get returned “a”, the zeroth element in the array. So far, so good. However, were you then to type “a”[1] into the console, you’d get returned undefined, which makes sense because in a single element array there will only the element at index 0, and no other, so any index above zero will return undefined.

So “a” which we know is the same as [“a”] is also technically equivalent to [“a”, undefined]!

In short, when comparing strings with greater-than or lesser-than operators, the shorter string will be “appended” with undefined instances when converted to an array until both arrays are of equal length before doing the final series of comparisons. And because undefined is a falsy value, when compared, the undefined gets coerced to 0.

With all that said and done, we finally end up with: [97,98] (“ab”) and [97,0] (“a”). Comparing the two arrays, We get the zeroth elements not satisfying the > operator, but the first elements do, so true is returned.

Finally, we compare “ate” with “are”. When both strings are converted to numeric arrays for comparison we have [97, 116, 101] and [97, 114, 101] . The rest is a foregone conclusion:

Index 0; is 97 > 97? No, move onto index 1.

Index 0; is 116 > 114? Yes! Ding Ding Ding! Stop processing and return true.

So there you have it, string comparisons with lesser-than and greater-than operators. And yes, it’s a pain in the ass that JavaScript computes comparisons like this, but once you stop and look at the process of how it does it, there’s a greater appreciation of how the language works.

#BecauseJavaScript

I hate people who whine about the eccentricities of JavaScript. “Oh, JavaScript doesn’t do what I expect it to when I do XYZ, it does ABC instead… #BecauseJavaScript.” – treating the language like it’s something they have to lump with because they have no choice…

A word to the wise: if you don’t like JavaScript, choose another language to code in and move on. I’m sick to death of these people that bemoan the fact that JavaScript doesn’t behave the way they expect it to.

If you take a step back to consider what is actually happening, then it ends up making sense and you can actually embrace the language for what it really is – truly insane. I’ve gone past that point and become somewhat insane myself, mainly because of my fondness for the language.

So where do we go from here? Let’s take a look at what some developers have tweeted with #BecauseJavaScript:

Jose Luis Cortes tweets:

Okay, so let’s re-write this so that we can see the code statement by statement and we’ll break down the conundrum right here, right now. I’ll place comments here and there within the code to explain what’s happening…

var a = b = [];

Okay, so we’ve defined two arrays, a and b… Note, that this notation doesn’t mean that a and b will remain equal to one another regardless of what happens to a or b, far from it. Using this kind of notation simply allows you to define a number of variables simultaneously to the same initial value, in this case the empty array. So, both arrays A and B are both set to []. So far, so good.

a['a'] = 0; a['b'] = 1;
b[0] = 0; b[1] = 1;

So what’s happening here? Two similar, but different types of array population. Array A is being set as an associative array (also known in some circles as a hash array.) Associative arrays allow you to “associate” various text-based keys with values. Associative arrays are what JSON objects are based on. As a result, you have a word association of sorts with each key-value pair… It’s actually pretty cool.

So, the first line of the two lines above sets two key-value pairs. One assigning the value of 0 to the key ‘a’, and the other the value of 1 to the key ‘b’. Now, the thing about associative arrays, is that unlike standard dimensional arrays, you don’t have to remember in which order the index lies, whether it was the very first index, or the twenty-seventh. Each item in an associative array is just “indexed” by its text key, so that it’s easier to remember. Associative arrays can also have other associative arrays or indexed arrays as values… So you can have layer upon layer upon layer… it’s very “Inception”-esque.

The second line is with respect to the more traditional indexed array, zero-based and everything. Here, Array B has two values set, the values 0 and 1 are defined for indices 0 and 1 respectively.

a.length //0
Object.keys(a)//["a","b"]
b.length //2
Object.keys(b)//["0","1"]

a.length… What is the length of an associative array? Technically, it’s undefined, so Jose isn’t quite right by expressing zero… The closest thing you can get to obtaining a “length” is by obtaining a number of the top-level keys being used. In a “flat” associative array, this would be equal to the number of keys, for example:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;

In this case, we know just by looking at the code that there’s 3 key-value pairs. But obtaining that amount works better using:

 Object.keys(myArray).length // returns 3

Anything deeper than a one dimensional associative array and it becomes a bit of a rabbit-hole. This differs in Array B however, where we have a clearly defined number of elements, in this case b.length will return 2 as its length.

The code used to generate the keys in both instances also gives testament to what each of these arrays is. The code is virtually identical except for the array being referenced. Both responses are correct, Array A having keys of ‘a’ and ‘b’, whereas Array B has “keys” of 0 and 1… Now there’s no trickery, this is correct, it’s all correct.

Indices do serve as primitive keys to the users who are working these, key 0… key 1… It makes sense. So it should!

So there’s nothing occult, or magical, or mysterious about the code… it plays out how it should and does not scare you if you know how it works. I’ll address a few more #BecauseJavaScript tweets later on in this blog in the next upcoming posts.

“Ich liebe #Javascript…”

I came across the following tweet the other day…


In it was an image containing a number of little JavaScript quirks I had yet to address but planned to in my next post… But things like renovating a new house and looking after my son have kinda taken a higher priority… But you know what, there’s no time like the present…

So, let’s take a closer look at the image posted by @nodenow:

We’ll address these one by one, and I’ll explain them all…

  1. ‘5’ – 3 (result: 2)
    Why does subtracting a number from a string of a number result in a number? The  operator does one thing and one thing only in between operands like this, it subtracts. When you have a subtraction happening both operands will be coerced into numbers. The 3 already is a number, but the ‘5’ gets coerced to its numeric equivalent, 5. 5 minus 3 results in 2, our answer.
  2. ‘5’ + 3 (result: “53”)
    To those believing that the + here behaves in the same way as the in the previous example, it could not be further from the truth. Because at least one of the operands is a string, the + is automatically converted from its regular function of adding two numbers together, and now becomes a concatenation operator. In fact, as a rule if there are two operands surrounding a +, if at least one of those operands is a string, the + is no longer a simple addition operator, but it will always become a concatenation operator. As a result, both operands will be converted to strings. ‘5’ stays as it already is, and the 3 will be converted to ‘3’. So as a result, adding ‘5’ to 3, results in the concatenation of ‘5’ and ‘3’ which ends up as ’53’.
  3. ‘5’ – ‘4’ (result: 1)
    Similar to our first example, the is a subtraction operator, always. So as a result the two strings will be coerced into their numeric equivalents of 5 and 4, and then the subtraction will occur after that. 5 minus 4 is, of course, 1, our final result.
  4. ‘5’ + + ‘5’ (result: ’55’)
    Bear in mind that the space in between the two plus signs is intentional… Removing the space will result in a Syntax Error due to the introduction of the increment operator (++) on an invalid increment operand. So what’s going on here? Here we have two similar but very different operators at work… the + before the second ‘5’ acts as a unary operator, which converts that second ‘5’ to a numeric 5, which results in ‘5’ + + ‘5’ really being ‘5’ + (+’5′), which is then converted to ‘5’ + 5, which is similar to our second example. So we apply similar behavior to our current example, ‘5’ + 5 converts the numeric 5 to its string equivalent of ‘5’, which means ‘5’ + + ‘5’ becomes ‘5’ + 5, which in turn becomes ‘5’ + ‘5’, which is a concatenation, which results in ’55’. Bear in mind, that a unary operator has a higher priority than a concatenation operator, and so unary operators will always be resolved first.
  5. ‘foo’ + + ‘bar’ (result: ‘fooNaN’)
    So we weren’t satisfied enough to just do it with numbers, we decided to throw foo and bar into the mix! The logic is the same as the previous example, but with slightly different results. the unary operator before the ‘bar’ string tries to convert it to a number, but without success, and so it reports back as Not a Number, a.k.a., our old buddy NaN. Add NaN to any string, and it will kick into concatenation mode, converting the paradoxical number NaN into ‘NaN’, which allows ‘foo’ to concatenate with it, forming ‘fooNaN’.
  6. ‘5’ + – ‘2’ (result: ‘5-2’)
    Another case of concatenation and other operators. In this case, we have a concatenation operator and a negation operator. Like the unary operator, it will take higher priority than the concatenation operator and thus will be resolved first. So ‘5’ + – ‘2’ will be interpreted as ‘5’ + (-‘2’), which in turn gets interpreted as ‘5’ + (-2). A string and a number with a plus sign in between will always be interpreted as a concatenation operator and thus the -2 will be converted to ‘-2’. So in the end we have ‘5’ + ‘-2’ which gets evaluated to ‘5-2’, our final result.
  7. ‘5’ + – + – – + – – + + – + – + – + – – – ‘2’ (result: ‘5-2’)
    Before I go explaining this one, a quick message to the person who originally created this image and chose this particular piece of code to demonstrate the quirks of JavaScript, whomever they are…I hate you…Now then… This particular question’s solution is based solely on the fact that the + and operators, whether we’re talking about addition, unary or concatenation or negation or subtraction, that all five of these types of operators are evaluated from right to left. This in mind, the last operator is a + near a string, so a concatenation operator. Lucky us! We know the answer is going to be a string of some sort!So, let’s go from right to left, solving it as we go:

    ‘5’ + – + – – + – – + + – + – + – + – – – ‘2’ (Our original statement)

    ‘5’ + – + – – + – – + + – + – + – + – – -2 (The last next to the 2 coerces our string to a number and at the same time negates it)

    Now comes the fun part. We now start consolidating operators using the following rules:

    • – -2 becomes +2;
    • – +2 becomes -2;
    • + -2 becomes -2;
    • + +2 becomes +2;

    So from:

    ‘5’ + – + – – + – – + + – + – + – + – – -2

    we get the following sequence of reduction:

    • ‘5’ + – + – – + – – + + – + – + – + – – -2
    • ‘5’ + – + – – + – – + + – + – + – + – +2
    • ‘5’ + – + – – + – – + + – + – + – + -2
    • ‘5’ + – + – – + – – + + – + – + – -2
    • ‘5’ + – + – – + – – + + – + – + +2
    • ‘5’ + – + – – + – – + + – + – +2
    • ‘5’ + – + – – + – – + + – + -2
    • ‘5’ + – + – – + – – + + – -2
    • ‘5’ + – + – – + – – + + +2
    • ‘5’ + – + – – + – – + +2
    • ‘5’ + – + – – + – – +2
    • ‘5’ + – + – – + – -2
    • ‘5’ + – + – – + +2
    • ‘5’ + – + – – +2
    • ‘5’ + – + – -2
    • ‘5’ + – + +2
    • ‘5’ + – +2
    • ‘5’ + -2

    So what happens? As I mentioned in the previous example, a string and a number with a plus sign in between will always be interpreted as a concatenation operator and thus the -2 will be converted to ‘-2’. So in the end we have ‘5’ + ‘-2’ which gets evaluated to ‘5-2’, our final result.

  8. x = 3; ‘5’ + x – x; ‘5’ – x + x; (results: 50 and 5)
    Our previous example only had two operands, and in both of these statements we have three. As a result, everything with three or more operands needs to be evaluated left-to-right. So in the first part:

    ‘5’ + x – x
    , which substituting using x = 3 we get: ‘5’ + 3 – 3

    We have ‘5’ concatenating to a number, forming the string ’53’; and then subtracting 3, forcing ’53’ to be converted to a number, 53, before subtracting 3, making 50.

    Our second statement evaluates as, ‘5’ – 3 + 3, where the ‘5’ is coerced by the subtraction operator to become 5, before subtracting 3, making 2, and then the addition operator adds 3 back again to make 5.

So there you go… Completely explained… If you have any questions, please feel free to ask by dropping a comment or two below!