THIS, Function Context, And Object Literals In Javascript

Posted October 13, 2009 at 8:42 AM

Tags: Javascript / DHTML

In Javascript, the "this" keyword points to the context of the currently executing function. Previously, I had thought that "this" would only work at the object level (treat the object as the context) if the given object was created using the "new" operator. Last night, while finishing up jQuery In Action, I found out that this is not true. A function's context will correctly bind to the parent object even if that parent object is defined as an object literal.

To see this in action, take a look at the following example:

 Launch code in new window » Download code as text file »

  • <!DOCTYPE HTML>
  • <html>
  • <head>
  • <title>Function Context And Object Literals</title>
  • <script type="text/javascript">
  •  
  • // Define an object literal with properties as well as
  • // a few accessor (getter) methods. Notice that the
  • // accessor use the THIS reference, which will properly
  • // define the context as the parent object, "girl".
  •  
  • var girl = {
  • name: "Phoebe",
  • hair: "Brunette",
  •  
  • getName: function(){
  • return( this.name );
  • },
  • getHair: function(){
  • return( this.hair );
  • }
  • };
  •  
  •  
  • // Call one of the object methods to see what the given
  • // function context is (what the THIS will point to).
  •  
  • console.log( girl.getHair() );
  •  
  • </script>
  • </head>
  • <body>
  • <!--- Nothing here. --->
  • </body>
  • </html>

As you can see, we are creating the object - girl - as an object literal using JSON (Javascript Object Notation). The object contains two properties and two accessor methods. The accessor methods both make reference to the "this" keywords which points to the function context. Because the context properly binds to the parent object - girl - calling the accessor method in the code above returns the corresponding property:

Brunette

That's good to know. I think I still prefer creating objects using Function definitions and the "new" operator as it provides a mechanism for multiple instantiation; but, when I need a really lightweight object definition, this seems like a nice approach.

Download Code Snippet ZIP File

Post Comment  |  Ask Ben  |  Permalink  |  Other Searches  |  Print Page



Learning ColdFusion 9 - ColdFusion 9 tutorials, samples, examples, demos

Reader Comments

Oct 13, 2009 at 9:56 AM // reply »
15 Comments

I absolutely does, and is quite useful. Where things get hairy is that jQuery callbacks alter the THIS scope, and it varies based on what the function executing the callback is (eg. $.ajax success callback, THIS = the ajax parameter object).

This is pretty easily solved by keeping a copy of THIS in a variable (eg. var __this = this;), and from there closures can bubble back up the parent to get to the original THIS via our copy.

Good stuff, and keep up the blogging Ben.


Oct 13, 2009 at 11:13 AM // reply »
6,516 Comments

@Adam,

Yeah, the jQuery stuff is cool though. I think you just start to get used to it. Once you accept the fact that "this" rarely points to the jQuery collection (outside of plugin development), you kind of just assume the next most appropriate thing - the raw element in question.


Oct 13, 2009 at 4:21 PM // reply »
1 Comments

Right, 'this' is determined at the time a function is called. It has no relation to how the object is created or what type of object it is.

When you call any function using foo.bar() notation, 'this' is the foo object.

It also works the same way when you call the function with foo['bar']() or foo[variableContainingMethodName]() notation.

You lose the connection to the original object if you take a reference to the function:

var moo = foo.bar;
moo(); // 'this' is the window object!

As you know, you can also explicitly set 'this' at the time you call a function:

bar.apply( someObject ); or
bar.call( someObject, arg, arg );

Inside the 'bar' function, 'this' will be the someObject you passed in.


Oct 15, 2009 at 8:32 AM // reply »
6,516 Comments

@Michael,

I rather like this. ColdFusion works in the same way - functions are given context only when they are called as a member of a given object.

For some reason, I just had it in my mind that if an object wasn't created using new/() then it would be bound to the window.

This is way cool though.


Post Comment  |  Ask Ben

Recent Blog Comments
Nov 21, 2009 at 11:03 AM
Groovy Operator Overloading Does Not Work In The ColdFusion Context
Hi Ben, Thanks for this informative post. Now I am reading ur old posts too ... read »
Nov 21, 2009 at 10:56 AM
HostMySite.com Has The Best ColdFusion Hosting
@Mehul, Yes very nice people, however several downtimes per day which was not acceptable. Hence we had to move out. I am glad you are having good luck with them so far. ... read »
Nov 20, 2009 at 11:32 PM
Five Months Without Hungarian Notation And I'm Loving It
I've used headless camel case for years for not only ColdFusion variables, but also SQL tables and fields... pretty much everything involving code. I also subscribe to the "don't abbreviate and clea ... read »
Nov 20, 2009 at 11:00 PM
Five Months Without Hungarian Notation And I'm Loving It
@Marcel, Yeah, I always err on the side of longer but more readable variable names. As for the camel casing of CF methods and the headless camel casing of custom items, I get around this by always ... read »
Nov 20, 2009 at 10:56 PM
Five Months Without Hungarian Notation And I'm Loving It
I use the following and love it: my.namespace.MyComponents.functionMethodsOrUDF() CONSTANT_VALUES_OR_PROPERTIES One thing I always try is to CamelCaseBuiltInColdFusionFunctions() so others can tell ... read »
Nov 20, 2009 at 5:38 PM
Learning ColdFusion 8: CFImage Part I - Reading And Writing Images
Hi Ben, Great article. I've been looking around to see if ColdFusion image engine can programatically create the following "wrap around" effect: http://www.creativepro.com/article/photoshop-s-she ... read »
Nov 20, 2009 at 5:35 PM
Maintaining ColdFusion Sessions Across SMS Text Message Requests Without Cookies
@Dave: I talked to Gert he suggested: <cfhttp method="get" url="http://{some cf website}" result="stuff" addtoken="yes" /> Note the addition of cfhttp attribute addtoken. That should persist y ... read »