What is ‘this’ in JavaScript?

JavaScript is a great programming language. That would have been a controversial statement a few years ago, but developers have rediscovered its beauty and elegance. If you dislike JavaScript, it’s probably because:

  • You’ve encountered browser API differences or problems — which isn’t really JavaScript’s fault.
  • You’re comparing it to a class-based language such as C++, C# or Java — and JavaScript doesn’t behave in the way you expect.

One of the most confusing concepts is the ‘this’ keyword. In most languages, ‘this’ is a reference to the current object instantiated by the class. In JavaScript, ‘this’ normally refers to the object which ‘owns’ the method, but it depends on how a function is called.

Global Scope

If there’s no current object, ‘this’ refers to the global object. In a web browser, that’s ‘window’ — the top-level object which represents the document, location, history and a few other useful properties and methods.


window.WhoAmI = "I'm the window object";
alert(window.WhoAmI);
alert(this.WhoAmI); // I'm the window object
alert(window === this); // true

Calling a Function

‘this’ remains the global object if you’re calling a function:


window.WhoAmI = "I'm the window object";

function TestThis() {
	alert(this.WhoAmI); // I'm the window object
	alert(window === this); // true
}

TestThis();

Calling Object Methods

When calling an object constructor or any of its methods, ‘this’ refers to the instance of the object — much like any class-based language:


window.WhoAmI = "I'm the window object";

function Test() {

	this.WhoAmI = "I'm the Test object";

	this.Check1 = function() {
		alert(this.WhoAmI); // I'm the Test object
	};

}

Test.prototype.Check2 = function() {
	alert(this.WhoAmI); // I'm the Test object
};

var t = new Test();
t.Check1();
t.Check2();

Using Call or Apply

In essence, call and apply run JavaScript functions as if they were methods of another object. A simple example demonstrates it further:


function SetType(type) {
	this.WhoAmI = "I'm the "+type+" object";
}

var newObject = {};
SetType.call(newObject, "newObject");
alert(newObject.WhoAmI); // I'm the newObject object

var new2 = {};
SetType.apply(new2, ["new2"]);
alert(new2.WhoAmI); // I'm the new2 object

The only difference is that ‘call’ expects a discrete number of parameters while ‘apply’ can be passed an array of parameters.

That’s ‘this’ in a nutshell! However, there are several gotchas which may catch you out. We’ll discuss those in my next post…

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Peter Galiba

    And don’t forget about primitives that are the context of the functions, when called by `call` or `apply`. In that case the primitives like boolean, number and string are converted to the Object counterpart of the primitive value.
    Just look at the following script:

    var values = [0, true, "string", NaN, undefined, null], i = 0, l = values.length, value;
    function typer() { console.log(‘INSIDE: value: ‘, this.toString(), ‘, type: ‘, typeof this); }
    while (i < l) {
    value = values[i++];
    console.log('OUTSIDE: value: ', value, ', type: ', typeof value);
    typer.call(value);
    }

    The following output is written to console:

    OUTSIDE: value: 0 , type: number
    INSIDE: value: 0 , type: object
    OUTSIDE: value: true , type: boolean
    INSIDE: value: true , type: object
    OUTSIDE: value: string , type: string
    INSIDE: value: string , type: object
    OUTSIDE: value: NaN , type: number
    INSIDE: value: NaN , type: object
    OUTSIDE: value: undefined , type: undefined
    INSIDE: value: [object Window] , type: object
    OUTSIDE: value: null , type: object
    INSIDE: value: [object Window] , type: object

    So the null and undefined values when used as `this` will be converted to the global object.

    Also don't forget about strict mode, which changes the meaning of this. When calling a function, the `this` will not be converted into the global object, not even with null or undefined set as the `this` in case of `call` or `apply`. In that case `this` will be null or undefined.

  • Bob

    Okay, this article makes no sense to me at all. What exactly is “this” and why is it used at all? It seems to just be a substitute for a variable, but you cannot tell at all from this article, which seems to assume you know how “this” is used in other programming languages. Is “this” useful? Why use it when other methods of programming are much more clear? I’ve written thousands of line of workable and efficient code that is very easy to understand and follow without using “this” once.

    • http://www.optimalworks.net/ Craig Buckler

      You’ve never used ‘this’ once? It’s essential if you’re doing any type of object-orientated programming in JavaScript (or any other language).

      JS doesn’t force you to use OOP, but the concepts remain useful if you’re writing reusable code.

  • Trent Reimer

    Good examples.

    “‘this’ remains the global object if you’re calling a function”

    Looking at it that way the behaviour appears consistent. A function is basically a method of the global object, isn’t it?

    • http://www.optimalworks.net/ Craig Buckler

      Thanks Trent — yes, that’s correct and a good way to remember it.

  • CandleForex

    If a person is going to use javascript, they would be well advised to use GZIP compression and browser caching using .HTACCESS.

    I have seen speed increases for everything (php, javascript and html etc…everything literally) of up to 70%.

    Its very simple to do, just add the two variables into your .htaccess:

    # BEGIN FORCE USE OF BROWSER CACHE
    FileETag MTime Size

    ExpiresActive on
    ExpiresDefault “access plus 1 year”

    #END FORCE USE OF BROWSER CACHE

    # BEGIN, compress certain file types by extension:

    SetOutputFilter DEFLATE

    # END Or, compress certain file types by extension

  • Juno

    yeah. I hate javascript’s this. Confusing. You can call me stupid hahah. Good writing.

  • DN

    very Nice work.

  • satya ……

    It was very nice. But recently I got an issue with firefox8(nightly build). Below are files to show the problem

    fiel1 : child.htm

    Home Page

    function callFunc(url)
    {
    sampleFunc();
    this.sampleFunc();
    }

    file2: home.htm

    Child Page

    function x()
    {
    var windows = [];
    }
    x.prototype.sampleFunc = function(val)
    {
    alert(this.frameElement)
    }
    function loadFun(url)
    {
    var iframeElem = document.getElementById(“loadFrame”);
    var iframeElemWindow = iframeElem.contentWindow;
    for (var i in x.prototype) iframeElemWindow[i] = x.prototype[i];
    iframeElemWindow.callFunc(“sampleURL”);
    }

    Steps to test:
    1. make sure src of loadFrame in home.htm is child.htm
    2. Open home.htm
    3. two alerts will come
    4. In all browsers except FF8-nightly build, I am getting both alert values loadFrame(HTML Element). But in FF8-nightly I m getting first alert as null and second alert value is loadFrame(HTML Element). “null is because”, “this” is referring to the window of the home.htm.

    Note: Logged a bug to firefox previously. They fixed and reverted the patch with following comment,
    “We fixed it, thanks again for filing it. We are now going to try breaking it again, in order to have simpler code and match the ECMA-262 Edition 5.1 spec extrapolated to work in the browser in the obvious way.”

    My Problem is, I have to get the frameWindow of loadFrame in the first call also(first alert). How can I get this?? Even using callee or caller combination doesn’t helped me. Plz help to get rid of this probelm.

    Thanks in advance