3.3. Language Anomalies

Despite using a familiar syntax with keywords you probably recognize, there are a couple of things about JavaScript that can catch you by surprise. The way objects are compared for equality is probably different than you expect. Moreover, the JavaScript language has the notion of objects being null or undefined. If you do not recognize these unique characteristics of JavaScript, you can get yourself into trouble and spend a lot of time debugging to find the source of the problem.

3.3.1. What Is Equality?

If you are just getting started with JavaScript and coming from a compiled language like C# or Visual Basic, be prepared for a whole new kind of debugging challenge! Not only is JavaScript typeless; it doesn't use a compiler! Remember it is interpreted. The only way to detect syntax errors, even simple ones, such as improper case, is to run the code. In addition, you must exercise every possible code path just to do what a compiler would do for you. This is one example of the huge benefit you can get from using the Microsoft ASP.NET AJAX Client Script Library: There is a large amount of fully debugged code ready for you to use in your own applications!

One thing to note is that JavaScript shares its treatment of Boolean values with the C programming language. JavaScript and C need a double equal sign for a logical test, and they use a single equal sign for an assignment. This can become painfully apparent when you find a missing equal sign in a comparison test. JavaScript programmers quickly find that assignment is not equality, except in the eyes of the script. Listing 3-12 attempts to test the value of the year variable but instead mistakenly includes only one equal sign instead of the required two. This means that this example is actually assigning a new value to the year variable, and the value of this assignment is nonzero, so when treated as a Boolean, the assignment evaluates to a value of true.

Example 3-12. Mistakenly assigning values to the year variable
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Assignment Is True</title>

    <script type="text/javascript">
        var year = 1970;

        if(year = 1968) {
          alert("This is true");
        }
        else {
          alert("This is false");
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>

    </div>
    </form>
</body>
</html>

You might be telling yourself that this is a silly mistake that you aren't likely to make yourself. If you are a C# programmer, you may be lulled into a false sense of security because the compiler catches these errors for you, but these kinds of errors are still common in the real world.

In addition, there is more to this comparison-testing subject in JavaScript. Even if you never accidentally use a single equals character instead of two, you might still not be safe from problems with equality checks. You may intend to test for equality, but JavaScript's type coercion can still prove to be a problem. Listing 3-13 shows an example of how mistakes of this nature are quite possible.

Example 3-13. More mistakes with JavaScript
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Equality</title>

<script type="text/javascript">
        var album;

        if(album == null){
         alert("album is null");
        }

        if ((album != true) && (album != false)) {
         alert("album is not true or false");
        }

        if(!album) {
         alert("but !album is true");
        }

        if (5 == "5") {
         alert("number 5 equals string 5");
        }

        if ((0 == false) && (1 == true) && (!0) && (1)) {
         alert("0 is false and 1 is true");
        }

        if (('true' != 1) && ('false' != false)) {
         alert("but 1 is not 'true' and false is not 'false'");
        }

        if ('undefined' == typeof(album)) {
         alert("the album type is undefined");
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
    </div>
    </form>
</body>
</html>

Consider the code from this listing. In this example, the album variable is defined and then checked with the equality operator against a value of null. In this example, it equates to a value of true. The album variable has not been assigned yet and when evaluated against null it is seen as equivalent.

var album;

if(album == null){
   alert("album is null");
}

The next check shows that the variable is not true or false when checked explicitly. After that, the album variable is treated as a Boolean, and by definition, a Boolean cannot be both not true and not false. It has to be one or the other, so it is coerced into one automatically, and JavaScript will treat it as false (the "!" not operator forces it to be treated as a Boolean even though we already determined that it is not a Boolean). Is your head starting to spin?

Other types will be coerced automatically for comparison as well. The next equality check shows the string 5 being compared to the number 5 and evaluating to a value of true. The number is coerced to a string for comparison purposes, similarly to the .ToString() method in .NET.

In JavaScript, a Boolean's true and false values are treated as one and zero, respectively. Zero is false, and a the one value is interpreted as true. However, the strings are not converted to equivalent Booleans, which hardly seems to make sense anymore.

The last comparison shows that JavaScript also has the concept of variables being undefined. Because nothing has been assigned to the album variable. At this moment, its type is undefined.

3.3.2. Null, Undefined, or Something Else

When working with JavaScript, the subtle difference between something being undefined or null can easily turn into a problem within your code. One approach is to take advantage of JavaScript's type coercion with a double negative. Instead of checking explicitly for undefined or null, you can apply the inverse operator twice:

if (!!something)
{

}

This approach can be extended to equality comparisons to avoid some of the confusion in the previous example in Listing 3-13. The string value of "5" is not really equivalent to a number value of 5 because the types are actually quite different, and in many cases you simply do not want them to be treated as equal.

JavaScript originally had the equality and inequality operators that were in earlier examples. Later in JavaScript's history, the strict equality and strict inequality operators were introduced. Instead of using two equal signs, you use three. This syntax results in a comparison performed without coercing types, so the types must be equal, and the values must be equal.

In Listing 3-14, this example duplicates the previous code listing but changes to using the strict equality and inequality operators. The results are more intuitive and generally different from the previous set of comparisons.

Example 3-14. Using strict equality and inequality operators
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Inequality</title>

    <script type="text/javascript">
        var album;

        if(album !== null){

alert ("album  is not null");
        }

        if ('undefined' === typeof(album)) {
            alert("the album type is undefined");
        }

        if ((album !== true) && (album !== false)) {
            alert("album is not true or false");
        }

        if (5 !== "5") {
            alert("the number 5 is not equal to the string");
        }

        if ((0 !== false) && (1 !== true)) {
            alert("false is not 0 and true is not 1");
        }
    </script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
    </div>
    </form>
</body>
</html>

In this example, notice that the undefined album variable is not strictly equivalent to a value of null. It is actually 'undefined', which means it does not have a type at that current moment in time. In addition, while it is undefined, it is neither true nor false as it was before with the standard equality operators. The number 5 is no longer considered equivalent to the string data type. Moreover, 0 and 1 are not really the same as true and false. Null is a value, not a type, and if you assign a null to a variable, it will take on the object type, which is not the same as having a type of undefined.

I recommend using the strict equality operators as your default for performing comparisons. You should use the original equality comparisons only when you specifically want the types to be coerced as part of the comparison. This will save you hours of frustration in the end.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset