Understanding Javascript automatic type conversion

4 Nov

Javascript is a language created for everybody: developers, designers, both advanced and beginners. That can be good and bad at the same time, what we can say is that it has been proven effective since is so widely used. The problem for advanced programmers is that it’s oversimplified and not strongly typed, at the same time, those two problems are the solution for designers and beginners. It makes it easy to get results without understanding what exactly is happening. But there are things in Javascript that need to be explained, someone cannot live their whole life without understanding what’s happening behind the scenes, it’s just not right. That’s why I’ll try to explain a few weird things that Javascript does to make it work for everybody.

Most of the weird stuff that Javascript does are related to it’s comparability to automatically type conversion, let’s see how that works.

Automatic type conversion

What are the results of the following statements?

function test1(){
	var result = (false == 0); //true
	alert("test1: " + result);
}
function test2(){
	var result = ("10" == 10); //true
	alert("test2: " + result); 
}
function test3(){
	var result = (" " == 0); //true
	alert("test3: " + result); 
}

Run test1 | Run test2 | Run test3

If you’re a designer or a beginner you’re probably thinking that they are all obvious, maybe except the test number 3. But a programmer will look at this with judgment eyes, specially tests 2 and 3. What happens is that Javascript is trying to make this code work so it will automatically convert the type of the values to be able to compare them.

On test 1 you are comparing a type “Boolean” with an “Integer”, but Javascript will automatically try to convert the Boolean to an Integer to compare them, and if you didn’t know this True is a 1 and False is a 0. This also happens in most of programming language because Boolean can always be converted to 0 and 1, they actually are 0 and 1.

Test 2 is the one that might drive some hate from experienced programmers. The first value is a string, and the second one is a Integer, they shouldn’t be compared because they have different types, but JS will magically try to convert the string in to a number to compare them, if you try the same example with “hi” == 10 the result will be false.

Test 3 proves that JS is made to be simple, comparing an almost empty string with zero will result true. Logically to achieve this in some other languages you would have to trim the string (get rid of the white spaces) and then compare it with an empty string (“”), resulting in a Boolean and then compare that with zero.

What about null and undefined

Let’s run some other tests:

function test4(){
    var result = (false == null); //false
    alert("test4: " + result);
}
function test5(){
    var result = (false == undefined); //false
    alert("test5: " + result);
}
function test6(){
    var result = (null == undefined); //true
    alert("test6: " + result);
}

Run test4 | Run test5 | Run test6

As we can see null, when compared with undefined will result in true. If you don’t know the difference between them, null is when you declare a variable that has the value null, undefined means that you never declared that variable, or that it was lost along the way.

So basically JS will not automatically convert null to Boolean(false) to compare it with false. Based on our first tests that would make some sense. The same happens for undefined.

Now let’s see a trick:

function test7(){
    var a; //a is null
    if(a)
        alert("test7: passed the if");
    else
        alert("test7: didn't pass the if");
}
function test8(){
    try{
        //a is undefined
        if(a)
            alert("test8: passed the if");
        else
            alert("test8: didn't pass the if");
    }catch(e){
        alert("test8:" e);   
    }
}

Run test7 | Run test8

If you run test 7 you’ll see that it wont pass the if statement, but wait a minute, we tried to automatically transform null to Boolean and it didn’t work! I know, logically an error should happen because on a strongly typed language the if statement only accepts a Boolean. As we can see, to make the language simpler JS will do more if you throw a variable to the if statement, if it’s null it will result in false, it it’s a string (not empty) or any integer greater than 0 it will result in true. Examples:

function test9(){
    var a = "Hi";
    if(a)
        alert("test9: passed the if");
    else
        alert("test9: didn't pass the if");
}
function test10(){
    var a = 25;
    if(a)
        alert("test10: passed the if");
    else
        alert("test10: didn't pass the if");
}

Run test9 | Run test10

On the other hand, test 8 will crash because you’re trying to use an undefined variable, but if null compared with undefined is true, why not do the same and let it just not pass the if. Well, I don’t know why, I just know that’s the way it is. Now, maybe you’re saying, “a” is not undefined, “a” doesn’t exist, so you have to get the type of “a”, that will give you undefined and it will work the way you want. Well, that’s what I thought, let’s try it out:

function test11(){
    try{
        //a is undefined
        if(typeof a) //type of a results in undefined
            alert("test11: passed the if");
        else
            alert("test11: didn't pass the if");
    }catch(e){
        alert("test11:" + e);   
    }
}

Run test11

As you can see it passed the if, but undefined when compared to null is true, now I throw that undefined in an if statement and it passes the if! Exactly, the problem is the result of typeof is a string: “boolean”, “integer”, “undefined”… Undefined in this case is a string! And as we saw before our friend JS will pass an if statement if the string is not empty. This is how we can make an if statement that will only pass if the variable is defined and not null:

function test12(){
    try{
        var a;
        if(typeof a != "undefined" && a)
            alert("test12: passed the if");
        else
            alert("test12: didn't pass the if");
    }catch(e){
        alert("test12:" + e);   
    }
}

Run test12

Conclusion

Javascript is very flexible, it’s made for novice to advanced programmers. If you’re starting to do development I would advice you to learn some other strongly typed programming language to help you learn good principles and best practices. Knowing only JS is really not good for your programming health, but once you get the main principles JS can give you some flexibility to make you life easier, that’s gonna be great if you know what you’re doing.