Object JavaScript – Using the ‘this’ Keyword

10063_580983808600819_401360548_nthis is a special word in JavaScript that is important whenever you are thinking in object-oriented terms.

The value of this inside a function, effectively depends on the object which called it. The ECMAScript Language Specification says, “The this keyword evaluates to the value of the ThisBinding of the current execution context.”

The use of the “this” keyword inside a function should be familiar to the C++/C# developers among us—it refers to the object through which the method is called ( developers who use Visual Basic should find it familiar, too—it’s called “Me” in Visual Basic).

This post borrows heavily from Daniel Trebbien’s response from JavaScript “this” keyword and some added examples from Ray Djajadinata’s article in MSDN Magazine, Create Advanced Web Applications With Object-Oriented Techniques.

The Value of this Depends on Context

We talked about scope in a previous posting in this series. Scope is when a variable name or other identifier is valid and can be used. Outside the scope of a variable name, the variable’s value may still be stored, and is not accessible in some way.

In JavaScript, when you define a variable inside a function, the variable is accessible inside that function. Any variable not inside a function is in the global scope and accessible everywhere in your code.

So what does that mean to the this keyword?

The ECMAScript Standard defines this as a keyword that “evaluates to the value of the ThisBinding of the current execution context”. ThisBinding is something that the JavaScript interpreter maintains as it evaluates JavaScript code, like a special CPU register which holds a reference to an object. The interpreter updates the ThisBinding whenever establishing an execution context in one of only three different cases:

Global Context

This is the case for JavaScript code that is evaluated when a <script> element is encountered:

https://gist.github.com/devdays/2fa1697fa84f4ab43fe7&lt;

When evaluating code in the initial global execution context, ThisBinding is set to the global object, window.

Entering eval code

The ThisBinding is updated

  • … by a direct call to eval()

    ThisBinding is left unchanged; it is the same value as the ThisBinding of the calling execution context.

  • … if not by a direct call to eval()

    ThisBinding is set to the global object as if executing in the initial global execution context.

§15.1.2.1.1 defines what a direct call to eval() is. Basically, eval(...) is a direct call whereas something like (0, eval)(...) or var indirectEval = eval; indirectEval(...); is an indirect call to eval(). See chuckj’s answer to (1,eval)(‘this’) vs eval(‘this’) in JavaScript? and this blog post by Dmitry Soshnikov for when you might use an indirect eval() call.

Inside a Function

We can say that every JavaScript function has a hidden argument named this. this always refers to the “owner” of the function we’re executing, or rather, to the object that a function is a method of.

For example:


function makeMeRed() {
var docBody = this.document.body;
docBody.style.background = '#cc0000';
}

In the function makeMeRed(), the owner is the page so this returns the window object.

If a function is called on an object, such as in obj.myMethod() or the equivalent obj["myMethod"](), then ThisBinding is set to the object. In most other cases, ThisBinding is set to the global object

The reason for writing “in most other cases” is because there are eight ECMAScript 5 built-in functions that allow ThisBinding to be specified in the arguments list. These special functions take a so-called thisArg which becomes the ThisBinding when calling the function.

These special built-in functions are:

  • Function.prototype.apply( thisArg, argArray )
  • Function.prototype.call( thisArg [ , arg1 [ , arg2, … ] ] )
  • Function.prototype.bind( thisArg [ , arg1 [ , arg2, … ] ] )
  • Array.prototype.every( callbackfn [ , thisArg ] )
  • Array.prototype.some( callbackfn [ , thisArg ] )
  • Array.prototype.forEach( callbackfn [ , thisArg ] )
  • Array.prototype.map( callbackfn [ , thisArg ] )
  • Array.prototype.filter( callbackfn [ , thisArg ] )

In the case of the Function.prototype functions, they are called on a function object, but rather than setting ThisBinding to the function object, ThisBinding is set to the thisArg.

In the case of the Array.prototype functions, the given callbackfn is called in an execution context where ThisBinding is set to thisArg if supplied; otherwise, to the global object.

Using the ‘new’ operator

When constructing a new object via the new operator, the JavaScript interpreter creates a new, empty object, sets some internal properties, and then calls the constructor function on the new object. Thus, when a function is called in a constructor context, the value of this is the new object that the interpreter created:


function MyType() {
this.someData = "a string";
}
var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);

Inside jQuery and Your own JavaScript libraries

Those are the rules for plain JavaScript. When you begin using JavaScript libraries (e.g. jQuery), you may find that certain library functions manipulate the value of this. The developers of those JavaScript libraries do this because it tends to support the most common use cases, and users of the library typically find this behavior to be more convenient. When passing callback functions referencing this to library functions, you should refer to the documentation for any guarantees about what the value of this is when the function is called.

If you are wondering how a JavaScript library manipulates the value of this, the library is simply using one of the built-in JavaScript functions accepting a thisArg. You, too, can write your own function taking a callback function and thisArg:


function doWork(callbackfn, thisArg) {
//…
if (callbackfn != null) callbackfn.call(thisArg);
}

Example

To summarize, every function object has a method named call, which calls the function as a method of the first argument. That is, whichever object we pass into call as its first argument will become the value of “this” in the function invocation.

Here’s an example of using this and showing how it changes as the object changes.


function displayQuote() {
// the value of "this" will change; depends on
// which object it is called through
console.log(this.memorableQuote);
}
var williamShakespeare = {
"memorableQuote": "It is a wise father that knows his own child.",
"sayIt" : displayQuote
};
var markTwain = {
"memorableQuote": "Golf is a good walk spoiled.",
"sayIt" : displayQuote
};
var oscarWilde = {
"memorableQuote": "True friends stab you in the front."
// we can call the function displayQuote
// as a method of oscarWilde without assigning it
// as oscarWilde’s method.
//"sayIt" : displayQuote
};
williamShakespeare.sayIt(); // true, true
markTwain.sayIt(); // he didn’t know where to play golf
// watch this, each function has a method call()
// that allows the function to be called as a
// method of the object passed to call() as an
// argument.
// this line below is equivalent to assigning
// displayQuote to sayIt, and calling oscarWilde.sayIt().
displayQuote.call(oscarWilde); // ouch!

The output is

It is a wise father that knows his own child.
Golf is a good walk spoiled.
True friends stab you in the front.

You can try it here: http://jsfiddle.net/w0ve2r04/1/

Best Practice

One thing to remember is never to call functions that contain “this” without an owning object. If you do, you will be trampling over the global namespace, because in that call, “this” will refer to the Global object, and that can really wreak havoc in your application. For example, below is a script that changes the behavior of JavaScript’s global function isNaN. Definitely not recommended


alert("NaN is NaN: " + isNaN(NaN));
function x() {
this.isNaN = function() {
return "not anymore!";
};
}
// alert!!! trampling the Global object!!!
x();
alert("NaN is NaN: " + isNaN(NaN));

Inside an Event

Inside an event, the owner is the HTML element the event belongs to. For example, in an onclick event, the owner is the element that fired the event.

In an event handler for an element, with default capturing (false), this will refer to the element which detected the event.


element.addEventListener('keydown', function (event) {
// `this` will point to `element`
}, false);

When capturing an event (true), say at the window level, event.target, will refer to the element which originated the event, while this will refer to the capturing element. For example:


window.addEventListener("error", function (event) {
event.target.src = 'some_path';
// `this` will point to window
// `event.target` will point to the element that had an error
}, true);

Call and Apply and Bind

You can use call(), apply() and bind()when you want that function to later be called with a certain context.

Use call(), apply() to call the function immediately, or use bind()to return a function that when later executed will have the correct context set for calling the original function. This way you can maintain context in async callbacks, and events.


function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(function(){sayHello.call(obj)}, 1000);

view raw

ojs-call.js

hosted with ❤ by GitHub

is the equilivant of:


function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(sayHello.bind(obj), 1000);

view raw

ojs-bind.js

hosted with ❤ by GitHub

Function.prototype inherits this

Where a function uses the this keyword in its body, its value can be bound to a particular object during execution using the call() or apply() methods that all functions inherit from Function.prototype.


function MyObject(element) {
this.elm = element;
element.addEventListener('click', this.onClick.bind(this), false);
};
MyObject.prototype.onClick = function(e) {
var dr;g = this; //do something with [self]…
//without bind the context of this function wouldn't be a MyObject
//instance as you would normally expect.
};

view raw

ojs-bind.js

hosted with ❤ by GitHub

When you want async callbacks and pass a member method for, but still want the context to be the instance that started the async action, you can use a simple naïve implementation of bind:


Function.prototype.bind = function(ctx) {
var fn = this;
return function() {
fn.apply(ctx, arguments);
};
};

Take the Quiz

Take the quiz offered by http://stackoverflow.com/questions/3127429/javascript-this-keyword

References

The this keyword

JavaScript this Keyword

Scope in JavaScript

Create Advanced Web Applications With Object-Oriented Techniques

js call() & apply() vs bind()?