Steve11235
Steve11235

Reputation: 2923

JavaScript strange null behavior

I have a good grasp on the difference between undefined and null and the fact that JavaScript casts just about anything to a boolean, in particular, null to false.

My question is this: Why is the second alert triggered in both FF 9 and IE 9? (This is a small test script that is based on much more complex script. It is meant only to illustrate the issue...)

I'm expecting the . operator to take precedence and the expression to return null, which would then be cast to a boolean value of false. Adding parenthesis, !(context.isNull), makes no difference.

<!DOCTYPE html>  
<html lang="en">  
  <head>  
    <title>Test</title>  
  </head>  

  <body>  
    <script type="text/javascript">  
        var context = this;  
        var isNull = null;  

        var aFunc = function() {  
            alert(context.isNull);  
            if (!context.isNull) {  
                alert("Is !context.isNull really true?");  
            }  
        };  

        aFunc();  

    </script>  
  </body>  
</html>  

Upvotes: 0

Views: 376

Answers (7)

Steve11235
Steve11235

Reputation: 2923

First, "Thank you!" to everyone who responded.

I'm deeply embarrassed. It was late Friday on a long day, and I inverted the logic in my head. It is doing exactly what it should. The problem was that the actual code was checking for something existing, and I wrote my test case backwards.

What happens is that null is cast to false, !false is true, so the "if" code is executed. My (brain dead) choice of field names obscures the problem.

The reason for

var context = this;

is that the real code sits inside a constructor. The field "context" is then "closed" when the function is created, which preserves a reference to the object being constructed. This is important when the function is attached to another object (generally as an event handler), so that the function body can access the contents of the original object. Of course, in the example, "this" refers to the global object, which doesn't serve much purpose.

Upvotes: 0

Selvakumar Arumugam
Selvakumar Arumugam

Reputation: 79830

Edit: I missed the context = this part.. As other mentioned, context = this => context = window.

Also, var isNull = null; in global scope implies => window.isNull = null.

Which will be as,

if (!context.isNull) => if (!window.isNull) => 
                          if (!null) => if (!false) => if(true)

if (!context.isNull) => if (!undefined) => if (!false) => if(true)

Upvotes: 0

Amber
Amber

Reputation: 526613

context.isNull is this.isNull is window.isNull which is null, which is boolean false. You're then adding !, which inverts that, resulting in an overall true expression, thus your if body is evaluated.

Upvotes: 1

leepowers
leepowers

Reputation: 38318

When placed in a boolean context a null value will evaluate to false. The unary negation operator ! casts the null to a boolean value - false - then flips the boolean to its opposite value: true. So ! does two things - it casts and flips.

Upvotes: 0

Dave Newton
Dave Newton

Reputation: 160191

Because this.isNull will evaluate to null. !null is truthy.

Upvotes: 0

Gus
Gus

Reputation: 6871

isNull is a local variable. It is not a property of the object presently represented by "this" if you add this.isNull = null or context.isNull = null you will get what you are looking for.

I think he's getting a true result because context.isNull is undefined and since undefined counts as a false result inverting it

Consider that this also produces the alert:

    var aFunc = function() {  
        alert(context.isNull);  
        if (!context.foo) {  
            alert("Is !context.isNull really true?");  
        }  
    };  

Upvotes: 0

ruakh
ruakh

Reputation: 183301

I take that you're expecting !null to be null? That makes sense — that sort of three-valued logic is used in SQL — but that's not how it works in JavaScript. In JavaScript, ! forces its argument to be interpreted as boolean value, and as you know, null, when interpreted as a boolean, becomes false.

Upvotes: 0

Related Questions