Testing for Strict Mode in JavaScript Using this

March 28, 2012

The this variable is an important concept in JavaScript and in many Object-Oriented languages. (Technically this is a keyword, but that’s a minor point in understanding it.) The simplest way to think of this is that it references the object whose method is currently being called. (The harder, but more accurate, way of thinking of this is as a representation of the execution context, but I find that definition makes a person blink a lot while simultaneously scratching his or her head.) The brilliant Peter-Paul Koch describes this as the “owner” of the current method, which also works.

To put this into a context (double pun), take the following JavaScript code, which defines a custom object, representing a rectangle:

var r = {
    side1: 10,
    side2: 20,
    isSquare: function() {
        return this.side1 == this.side2;
    }
};

That code defines an object with two attributes and one method. The method, called using the code r.isSquare(), returns a Boolean value indicating if the rectangle is also a square or not. Since the isSquare() method is defined as part of the r object, within that method, this refers to r.

this in JavaScript Example

Now take this code:

function returnThis() {
    return this;
}

In JavaScript running within the Web browser, any function defined outside of any object becomes a method of the global window object. Thus, in that code, this refers to the global window object.

this in JavaScript Example 2

Those two examples explain the simplest implications of the this keyword. However, as of ECMAScript 5, JavaScript now has a strict mode, triggered by adding the string use strict to a page or function:

function someFunction() {
    'use strict';
}
It is recommended that you use strict mode, and I certainly do in my “[intlink id=”3016″ type=”page”]Modern JavaScript: Develop and Design[/intlink]” book.  But when  you run JavaScript in strict mode, this behaves a bit differently. The specific difference occurs within functions that are not associated with objects, as in the returnThis() example. In non-strict mode, this represents the global object in such cases, as just shown. In strict mode, this will be undefined, as the association between the function and the global object is not meaningful, even though it exists:
function returnThis() {
    'use strict';
    return this;
}

This change in behavior is fine, though, as a function that’s not overtly associated with an object really shouldn’t be called obliquely on the global object via this anyway. Put more simply: it’s best that code not rely upon the assignation of functions to the global object. If a function needs to use a global object, it should do so overtly, such as referring to window. And strict mode is really geared towards fixing these kinds of oddities and inconsistencies.

Taking this knowledge one step further, because this is undefined in strict mode in functions not associated with objects, you can use that fact to test whether or not your JavaScript is working in strict mode. To do so, just create a function not associated with any object and have it return a Boolean indicating whether or not this is undefined:

function isStrict() {
    return (typeof this == 'undefined');
}

This can be shortened to just returning the oppposite of this:

function isStrict() {
    return !this;
}

If this is undefined, which translates to false, then true (the opposite) is returned. If this refers to an actual object, that translates to the Boolean true, so false is returned.

If your code might need to know the strict mode in several places, you can assign that status to a variable, thereby only invoking the function once:

var strict = isStrict();

Or you can turn this all into an immediately-executed anonymous function:

var strict = (function() { return !this; }());

Obviously, using a function to report on the strict mode only works if the entire JavaScript file is or is not invoking strict mode.

And that’s how the this keyword behaves differently in JavaScript’s strict mode, and how you can use that modified before to test for strict mode, too.