#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 capital ‘A’ isn’t 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. Stay quirky, people!

Advertisements

#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!

I Know, I Know, I Know This Much Is True (…or False)

So today, we’re talking Booleans. Booleans are, as you’re probably aware, one of two states: true or false. This is a beautiful thing… True or false, black or white, left or right, right or wrong, shaken or stirred, scrunch or fold… Sorry… Let’s digress…

 

Now, with Booleans you have the Logical NOT Operator, represented by our friend, the exclamation point, (the !) What the Logical NOT Operator does is take your object and go all truthy-falsy with it. Basically, the Logical NOT Operator is tasked with finding the logical opposite of whatever your object represents.

So based on the rules I mentioned about what is a truthy value and what is a falsy value we get a series of rules to live by. So let’s take a quick look at Boolean types.

  • If x is true, then !x==false
  • If x is false, then !x==true

This is pretty much the essence of it all… The Logical NOT Operator here acts as a “The Opposite Of…” operator. Opposite of true is false and vice versa… Let’s now push this further to numbers:

  • If x is zero, then !x==true
  • If x is non-zero, then !x==false

Okay, so zero, the only falsy value in the JavaScript natural number system is therefore the only number that will yield true when coerced by the Logical NOT Operator. Subsequently, all other numbers being truthy when coerced by a Logical NOT Operator will yield false. You may recall in one of my previous posts that !0 and !1 have occasionally been used as alternatives to true and false respectively. I will probably go a step further and say that if you were happy to push the boundaries of your code if minimizing or code-golfing, you could technically set specific Booleans to 1 and 0 to represent true and false respectively. Bear in mind the following:

While 0==false and 1==true,
!1===false and !0===true

If you’re scratching your heads about the differences between =, == and ===, let me illustrate it with a very simple set of rules that makes it easy to remember:

  • If you are assigning a variable, you only need the one =
  • If you need to compare values only, you need one more to get ==
  • If you want to compare values and object types, you need one more on top of that to get ===

So, let’s use these rules in a practical example which you can perform in the JavaScript console.

x = “5”; // We’ve set x to a string, typically numeric 5 as a string, NOT the actual number.
x == 5; // You’ll get true

This is because x is compared against the numeric version of the string, forcing the string “5” on the left hand side to be coerced into a numeric 5 to compare against the 5 on the right-hand side. As you’re comparing values, the now-numeric 5 on the left is compared to the existing numeric 5 on the right; 5 is equal to 5… As a result, you’ve got a true statement. But if we try this with === we get something quite different…

x === 5; // You’ll get false

Why do we get false this time around? In this case we’re now adding another level of comparison, we’re comparing against not only value, but object type… We’re comparing a string against a number. As a string is not a number (or vice versa), the === comparison operator fails right there and then, returning false.

So, bear that in mind if you’re thinking of taking some shortcuts with true or false.

So where were we? We’ve looked at Booleans, we’ve looked at numbers… Let’s take a look at strings and the effects of Logical NOT Operators on these:

  • If x is an empty string “”, then !x==true
  • If x is non-empty string like “margarita”, then !x==false

Empty strings are falsy values, and so a Logical NOT Operator on a falsy value will yield true. Consequently, a non-empty string, which is a truthy value when coerced by a Logical NOT Operator will naturally yield false.

Now it’s time for arrays:

  • If x is an empty array [], then !x==false
  • If x is non-empty array like [“margarita”], then !x==false

Herein lies the rub; we may be dealing with an empty array, but it is still a defined array. As a result, it still has value, and is thus truthy, thus ![] will yield false.

Bear in mind that an array with a falsy value as its only element (such as [“”] or [0]) is still a non-empty array, and like all non-empty arrays, will yield false when coerced by a Logical NOT Operator.

Now, back to objects… The truthy little buggers that they are. An object is truthy regardless of whether it is empty or non-empty. Case in point:

  • If x is an empty object {}, then !x==false
  • If x is non-empty array like [“pizza”:”supreme”], then !x==false

So, put simply, JavaScript object types don’t really respond well to change when it comes to coercing them to a Boolean with a Logical NOT Operator…

So, what do we do about the other objects – the dates, the functions, the regular expressions? We can test those out too… So, let’s take a quick look at Dates

!(new Date) // returns false

Why has it returned false? Date objects are truthy. And thus a Logical NOT Operator coercing a truthy value will result in false.

How about regular expressions? They’re truthy as well… Put a Logical NOT Operator in front of a truthy value and you will get false:

!/tic|tac|toe/ // returns false

Lastly, functions… Functions when coerced by a Logical NOT Operator act similarly to how functions behave when coerced by a unary or negation operator, the end result is basically what you get after the operator has acted on the return value of the function. If a function’s return value is truthy, the Logical Not Operator acting upon the function will result in false; whereas if a function’s return value is falsy, the Logical Not Operator acting upon the function will result in true.

Case in point: x = function(y) { return y + 1;}

  • !x == false
    x
    is defined, therefore truthy, thus !x is false.
  • !x(-1) == true
    x(-1) == 0, therefore falsy, thus !x(-1) is true.
  • !x(0) == false
    x(0) == 1, therefore truthy, thus !x(0) is false.

Let’s try a function with no return value: y = function(z) { var x = 17;}

  • !y == false
    y
    is still defined, therefore truthy, thus !y is false.
  • !y(27) == true
    There is no return value for the function, as y(27) returns undefined. Undefined is a falsy value, as a result, !y(27) is true.

So there’s the Logical NOT Operator and how Booleans can be coerced from other objects using it. The final operator of focus is the concatenation operator, which funnily enough is also represented by the + character. I’ll address the concatenation operator in my next post. Stay tuned!

Unary and Negation Operators Part 4 – Dates, Functions and Regular Expressions

I can only promise this post will be quick and painless… Kinda like ripping off a Band-Aid…

There were three final object types in JavaScript that hadn’t been taken into account with regards to Unary and Negation Operators; they are dates, functions and regular expressions… Let’s kick it off with dates…

Thing is with the Date object… One needs to declare a new instance before anything can really be done with it.

+Date // result is NaN

+(new Date) // result at time of running was 1438551674445.000000

Running the latter statement as +new Date works just as well, but for two less characters (see my upcoming post on code golf). But the result is basically the number of milliseconds since Epoch (January 1, 1970 00:00:00) began. So in essence you have a very large number, + and basically make it positive and negative. And that’s all there is with Unary and Negation Operators and date objects.

Next, I’m skipping to regular expressions as functions basically are capable of returning anything, including other functions… But we won’t be going into that… Regular expressions… these are the lovely things that look a bit like this:

/at|gn|mp|sc|-|’|((zi?|t)o|[hts]e|[lrd]ia)$/g

This was part of my entry for distinguishing regions of Italy against American states. Regular expressions are great for matching against certain sets of words, like in the example I’ve linked above. What they can’t do however, is translate well to numbers… Actually, they suck at it… Big time… Take our lovely example from the paragraph or so before…

x = /at|gn|mp|sc|-|’|((zi?|t)o|[hts]e|[lrd]ia)$/g; // x stores the RegExp
+x // result is NaN
-x // result is also NaN

Hmmm… what if, like strings, they were completely numeric? Still doesn’t work, told you before, regular expressions suck at this… they’re great for what they can do, but being coerced into numbers is not one of them:

x = /3456/; // Stored the regular expression of /3456/ to x
+x // NaN… still nothing…
-x // NaN… also nothing…

So, regular expressions are therefore pretty useless when it comes to coercing them into numbers. They’re great for other things, but just not for converting into numbers. So let’s put that to rest…

Finally, functions… Now I will assume that if you’ve been programming for some time that you know how a function works…

x = function (y) { return y*2; }

Simple function, number goes in, double the number goes out.

Now, as you’re dealing with something that provides a return value in this particular instance, +x(5) or -x(17) will provide a response that is basically the Unary or Negation Operator working on the return value. In the case of +x(5), this will return +(10) which will then become 10. -x(17) will return -(34) which will then become -34. If the return value of a function was a string, the Unary or Negation Operator would interact with that to provide the final result, and so on.

So general rule is, if a Unary or Negation Operator is coercing a function, the final product from this coercion is the result of the Unary or Negation Operator acting on the function’s return value.

What if there’s no return value? Let’s test it out with an example:

y = function() { var x = “42”;}

Even expecting a return value on this function is unheard of, and the JavaScript console responds in kind with undefined. Well, when you think about it, that makes a lot of sense. We haven’t defined a return value on y() and therefore the undefined is definitely appropriate!

So bearing this in mind, using a Unary or Negation Operator on a function that has no return value is the same as trying to coerce undefined with a Unary or Negation Operator; and as a result in either case, the result is our lovely friend NaN.

So there’s Unary and Negation Operators sorted. In my next post I’ll move onto other operators, and hopefully provide a quicker run-down on how these other operators affect JavaScript object types.

Until then!

Unary and Negation Operators Part 3 – Arrays and Objects

Are you sitting comfortably? Great! Let’s pick up where we left off!

We talked about the affect of UNOs (Unary and Negation Operators) on Booleans and numbers in my last post. I’ll now talk about arrays and objects and how UNOs affect them.  We’ll be dealing with truthy and falsy values as I did in that last post because now that you know about them, you’ll be able to spot these a lot sooner.

Now, I mentioned that falsy values yield false when coerced to a Boolean, and truthy values yield true when coerced to a Boolean.

When it comes to objects and arrays, a UNO will coerce these “differently” . Let’s take a look:

Empty Objects and Arrays

  • +[] == 0
  • -[] == 0

An empty array is a straight-out falsy value. It will coerce straight to 0 regardless of which UNO you use.

  • +{} == NaN
  • -{} == NaN

Whereas the empty object suffers a crueler fate by not even being able to cast to a number! Even though an empty object’s nature, being truthy, it still becomes coerced to Not a Number. It weird and it sucks, I know, but this is how JavaScript rolls…

“Not-So-Empty ” Objects and Arrays

So let’s see what happens when we put different content in these and then true coerce them with a UNO. The correct way with regards to objects is a key and value pair like {x:y}. Anything other than this or an empty object and we wind up with syntax errors.

+{x:27} == NaN

-{x:27} == NaN

+{x:”eggs”} == NaN

-{x:”eggs”} == NaN

We’re off to a great start here… This doesn’t help us one bit… Objects just simply coerce to NaN with a UNO. The empty object version +{} may help us in the long run (to which I will explain later) but the other instances are simply useless.

Let’s try an array with one element:

+[27] == 27

+[“27”] == 27

+[“eggs”] == NaN

So… Here’s what we’ve learned. Not much either… It’s kinda cool that an array with a number or its equivalent string will both coerce to the said number with a UNO, but trying to do this with any other string in an array – pointless, another NaN. I can see +[] will come in useful later but I will also talk about that and +{} in a future post.

Beyond this, we will conclude by saying that objects of any size or arrays of any size greater than one without a number in numeric or string form will coerce out as NaN. I honestly thought I had more to give on this particular post… Let’s see what we have left… Functions, Regular Expressions and Dates… Let’s hit those in my next post…

Until then!

Unary and Negation Operators Part 2 – Numbers and Booleans

Hi again! Now, last I spoke (er… wrote) I had been going ad nauseum regarding the affects of unary and negation operators on strings. Today, I’ll be focusing my efforts with regards to these same operators but on a few of the remaining objects on the list: booleans and numbers… The others I’ll handle in future posts.

So, Unary and Negation Operators (which I’ll call UNOs for short) yield interesting results when combined with other JavaScript object types. We dealt with strings and the effects of UNOs on them in my last post; so as numbers will be relatively simple I’ll just blitz through this part…

+5 == 5
-5 == -5
-(-5) == 5

Well… Surprise, surprise… The plus and minus do the exact expected thing one would expect in standard mathematics…

The only exception to this is --5. --5 actually won’t evaluate as the -- operator is reserved for pre-decrement and post-decrement of variables, and not numbers… For the negation of a negative number parentheses need to be used, as per my last example.

And that’s UNOs with numbers… I told you it’d be quick…

Now we get to the interesting parts. Let’s start with booleans…

+false == 0
+true == 1


Okay, to understand why coercing false to a number results in zero, and why true is coerced to 1, I need to get into truthy and falsy values… Truthy and falsy values have the following traits:

  • Truthy values will coerce to true when converted to a Boolean. Examples of truthy values are all natural numbers both positive and negative (excluding zero), and non-empty strings, and all empty and non-empty arrays and objects. Basically any value that has definition, is not null, or zero, or empty qualifies as a truthy value (…and empty objects and arrays, I wish someone can explain this to me… That’s just plain weird). True as well counts as a truthy value.
  • Falsy values will coerce to false when converted to a Boolean. Examples of falsy values are zero, empty strings; null, NaN (Not a Number) and undefined. Naturally, false also counts as a falsy value.

So how do you test whether a value is truthy or falsy? You know how they say “two wrongs don’t make a right”? JavaScript have taken this concept and twisted it on its head. JavaScript’s Logical NOT operator (!) converts true to false and vice versa… So combining two of them you have a falsy/truthy operator which is capable of taking any value and determining if it is truthy or falsy. !! spits out true for truthy values and false for falsy values. It really is that easy.

So where am I leading with this? If you’ve been programming for a while, you’ll have come across similar examples of truthy and falsy values at work, probably without you realizing it:

var x=10;
while(x){
   f(); x--;
}

The while loop and the for loop are notorious for abusing the concepts of truthy and falsy values. See that solitary x in our example here? As you will know while loops work off a condition being satisfied to continue running. When the condition is no longer met, the while loop terminates and the code moves on. With each iteration the value of x decreases until it reaches zero. Once it does, the while loop finally converts zero to false and terminates. Similarly, you may have seen the following:

while(true) 

or

while(1)

Both statements mean the same thing… So, it would make sense that true and 1 are considered equivalent to one another logically. In fact, if you were to evaluate !!1 you would naturally get true, and evaluating +true will give you 1. Similarly, because zero is a falsy value you could conclude that !!0 would give you false, and therefore +false would give you 0.

And you’d be right…

Because 0 and 1 are falsy and truthy respectively they can technically be used as shortcuts for false and true respectively. While technically any number or truthy value could be used as a substitute for true, 1 is the simplest and quickest way. This little trick of using 0 and 1 as substitutes for false and true is often used in code golf (which I will cover in a later post) to conserve character usage. Basically, you’re saving 4 and 3 characters respectively.

So as a result:

+false == 0

and

+true == 1

In my next post, I will be addressing arrays and objects and how they react with UNOs. Stay tuned.