34

I have a function along the lines of the following:

    doSomething: function () {
        var parent = null;

        if (this === null) {
            parent = 'some default value';
        } else {
            parent = this.SomeValue();
        }
    }

Could parent ever be set to 'some default value' or is the check for null superfluous?

Alternatively, what if I used the less restrictive:

    doSomething: function () {
        var parent = this ? this.SomeValue() : 'some default value';
    }

Could parent ever be set to 'some default value' in this case?

Mark Robinson
  • 13,128
  • 13
  • 63
  • 81

6 Answers6

38

In non-strict mode, this has undergone an Object(this) transformation, so it's always truthy. The exceptions are null and undefined which map to the global object. So this is never null and always truthy, making both checks superfluous.

In strict mode, however, this can be anything so in that case you'd have to watch out. But then again you have to opt in for strict mode yourself, so if you don't do that there are no worries.

(function() {               return this; }).call(null); // global object
(function() { "use strict"; return this; }).call(null); // null

The specification of ES5 says:

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where a undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value.

pimvdb
  • 151,816
  • 78
  • 307
  • 352
  • It should be noted that attempting to call the "SomeValue()" function on an object without such a property might be cause for a *little* worry. – Pointy Mar 16 '12 at 15:21
  • Well, technically it hasn't always undergone `Object(this)`, since if it is an object, it doesn't, and more importantly, if it was initially `null` or `undefined` then it doesn't either, it's just directly set to the global object. – davin Mar 16 '12 at 15:22
  • @davin: Actually for an object it doesn't matter whether it does (`Object(obj) === obj`), but as for your second point, you're entirely correct. – pimvdb Mar 16 '12 at 15:24
  • I agree it doesn't matter, but the spec's algorithm doesn't specify that it undergoes Object coercion, so I was nitpicking (which wasn't very polite); i.e. I agree that the values are the same, but the procedure `Object(this)` would not be performed in such a case (http://es5.github.com/#x10.4.3). – davin Mar 16 '12 at 15:26
  • +1, but the example is rather contrived. In strict mode, `this` will be null in some "normal" cases - see the "Eliminates this coercion" section of http://www.nczonline.net/blog/2012/03/13/its-time-to-start-using-javascript-strict-mode/ – Gabe Moothart Mar 16 '12 at 15:38
  • @Gabe Moothart: Practically `this` will indeed never be `null` because you need to explicitly set it. Reading between the lines however, it looks like the OP also cares for `undefined` because it'd throw a similar error when accessing the function on it. – pimvdb Mar 16 '12 at 15:47
  • @pimvdb you're right, I wasn't properly distinguishing between `null` and `undefined`. Oh, the wonders of javascript :-) – Gabe Moothart Mar 16 '12 at 16:22
2

Although not a direct answer to your question.. in a browser 'this' will, by default, refer to the 'window' object. On nodejs it will refer to the global object.

I'm not sure if there's ever a case where it could be null, but it would at the very least be unusual.

Evert
  • 93,428
  • 18
  • 118
  • 189
  • Welp.. I'll leave my answer because it may be useful, but pimvdb has the better answer :) – Evert Mar 16 '12 at 15:16
2

The this keyword shouldn't ever be null, but it might not be what you expect. You can end up referencing the window object if you're not careful.

In your case, I believe this should refer to the doSomething function.

var myObject = {
    myMethod: function() {
        console.log(this);
    }
};

myObject.myMethod(); // prints out a reference to the myMethod function

Here's a jsFiddle.

Josh Earl
  • 18,151
  • 15
  • 62
  • 91
1

You can see what occurs if you try to force Javascript to use a null scope in any browser. I made an example here:

http://jsfiddle.net/rXsWj/

In short, this empirically proves that the browser changes 'null' to 'window' on the fly. If instead you change null to 'a', you'll see an alert of 'a' like you would expect. Code from link as reference:

function a() {
    alert(this)
}

a.apply(null)

sethcall
  • 2,837
  • 1
  • 19
  • 22
0

No. The value of this will never be the text 'some default value'.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

this can not be null. if it was null, then you couldn't be in method scope.

belgther
  • 2,544
  • 17
  • 15