“this” and “that”: understanding execution context in javascript

JavaScript is the type of language that causes massive amounts of confusion in people who are used to more structured OOP languages like C# or Java. One of the aspects of the language that is not always clear is how the “this” keyword works. Unlike other OOP languages, the value of “this” is not always what one would expect. Let’s look at an example in C#:

namespace StevenHunt.Demo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            ThisDemo demo = new ThisDemo("test value");
            Console.WriteLine(demo.This());
        }
    }
    public class ThisDemo
    {
        private string val = "";
        public ThisDemo(string val)
        {
            this.val = val;
        }
        public string This()
        {
            return this.val;
        }
    }
}

As you can see in the program above, “this” in C# is always a reference to the current instance of the parent object. In fact, if there is no parent object to reference such as in the case of a static method, you cannot use the “this” keyword without receiving a compiler error. You have no control as to what the value of “this” is; the reference is automatically handled by the language itself. As a side note, “this” has an alternate use in C# when defining extension methods. Extension methods are outside of the scope of this article, but I wanted to mention them since they share the same keyword. Anyways, back to JavaScript…

In JavaScript, “this” is a valid keyword in any context, so what value could it possibly be referencing in the global context? Let’s start with the simplest case:

<script type="text/javascript">
    alert(this);
</script>

What does this example do? It generates an alert with the contents of “[object] [Window]”. What does this mean though? It means that “this” is referencing the window object, also accessible in your client-side JavaScript code with the variable “window”. If you’re running code in a global context, “this” will always reference the window object. Before we move to more advanced examples, consider the following code:

<script type="text/javascript">
    function setName(context, name) {
        if (!context.demoName)
            context.demoName = name;
    }

    function writeName(context) {
        alert(context.demoName);
    }
</script>

For the purpose of demonstrating “this” in the following examples, I’ve written two functions: setName() tags a javascript object with a friendly name if it doesn’t already have one, and writeName() writes that name to the screen. Here is the same example already given, but using these new functions:

<script type="text/javascript">
    setName(window, "window");
    writeName(this);
</script>

So, in this simple example we’re going to tag the name “window” to the window object, and then write out whatever the name of “this” is. If we were to run this we would get this output: “window”. Why did we get that? because if you’re writing code in a global context, “this” is a reference to the window object. What about functions?

<script type="text/javascript">
    setName(window, "window");
    var func1 = function() {
        setName(this, "func1");
        writeName(this);
    };
</script>

What if we then were to simply call the function like this:

func1();

Calling the function produces the following output: “window”. We’re calling the function from the global context, so “this” still references the window object. Let’s do something different and instantiate an instance of func1:

var f1 = new func1();

Running this line of code would output “func1” onto the screen. Because we’re treating the function as an object definition, the “this” keyword now references the new instance of the object being created. As we can see, “this” is set to the new instance of the object, but what about methods defined within the object itself?

<script type="text/javascript">
    setName(window, "window");
    var func2 = function() {
        setName(this, "func2");
        this.func3 = function() {
            setName(this, "func3");
            writeName(this);
        };
    };
</script>

Then, let’s say we do the following:

var f2 = new func2();
f2.func3();

Running that code would produce “func2”. Because we’re treating func3 as an instance method of an object defined by func2, the context of “this” will be the instance of “func2” referenced by the variable “f2”. If you really want to warp your mind and embrace the insanity that is JavaScript, what happens if we do this?

var f3 = new f2.func3();

First off, is that even valid? Why yes… yes it is. Once you can accept that, what’s the output? It would be “func3”, since “this” would be a reference to the instance of func3 we’re instantiating.

The key to dealing with “this” in javascript is understanding that the value it references can be different at runtime depending on how the code its used in is called. To  make matters even more complicated (yet ultimately very powerful), you can manually set the context of a function call yourself. Here’s an example with func1:

var mycontext = {};
setName(mycontext, "my context");
func1.call(mycontext);

Running this code would output “my context” to the screen. Using the call method of a function, you can set the context of the function as well as pass parameters. You can do the same thing with apply, the difference being whether you want to pass parameters as parameters of the function or as an array. This technique is used frequently in JavaScript libraries like jQuery to provide a reference to callback functions for events.

There’s one more example I would like to provide on this blog post before wrapping up. In accordance with the title, I’ve talked about “this”, however I haven’t talked about “that”. So, what is “that”? It’s just something I made up, but it makes handling the following scenario much easier. Let’s say you’re trying to do something like this:

<script type="text/javascript">
    setName(window, "window");
    var func2 = function() {
        setName(this, "func2");
        this.func3 = function() {
            setName(this, "func3");
            setTimeout(function() {
                writeName(this);
            }, 1000);
        };
    };
</script>

This example is identical to the previous func2/func3 example, with the exception of writeName being called inside of an anonymous function passed to setTimeout. For instance, something like this might be expected if you’re performing asynchronous actions and some part of your code needs to be in a callback that runs later. Anyways, what’s the output? It’s “window”, which may or may not be ideal for your functionality. But what happened to referencing the parent instance? Well, your code is now inside of an anonymous function which is called by setTimeout, which is an instance method of the window object. Therefore, “this” will refer to the window object. so, let’s go ahead and add “that” into the mix:

<script type="text/javascript">
    setName(window, "window");
    var func2 = function() {
        setName(this, "func2");
        this.func3 = function() {
            setName(this, "func3");
            var that = this;
            setTimeout(function() {
                writeName(that);
            }, 1000);
        };
    };
</script>

Now what? The output returns “func3”, hooray! But why? Basically, we copied the reference from “this” into a variable called “that”. Thanks to JavaScript closure, a function defined within another function has access to that parent function’s variables. That way when your callback runs, it has a valid reference to the instance of the object you expect it to have. Keep in mind that this only works if the instance itself is still around in memory, otherwise it won’t work for obvious reasons. I would also like to make a note that this technique may not be ideal if you plan on instantiating several thousand objects, as JavaScript will have to make a copy of the parent function’s variables for each instance.

So there you have it, “this” and “that”. Enjoy!

Multiple sortable lists with drag-and-drop transfer using jQuery UI

The other day, I was looking at a piece of code on a project I’m working on where we’re using a jQuery UI sortable control to allow the user to re-order the elements in the list by dragging them. We wanted to be able to add multiple levels of containers in the list, so sortables inside of sortables. This would also mean that the user would need to be able to drag elements in the list to another list existing inside of the list itself, which presents a lot of confusing code problems. After looking online, there were a lot of confusing solutions which involved handling drag and drop events using draggable and droppable components. I didn’t have any luck with these, so I continued on and reviewed the documentation for sortable to find this gem: the connectWith property. You give it a selector, and it lets the elements in your sortable list be drag-and-droppable to any other sortable list that matches the selector. Here is a simple example:

$('.my-sortable').sortable({ connectWith: ".my-sortable" });

In this example, any element on the page with the class “my-sortable” becomes a sortable list whose items can be drag-and-dropped to any other sortable list using this class. It’s yet another example of a jQuery one-liner that takes something complicated to do by hand and turns it into an elegant piece of code.

New project: gearbox.js

GearboxOver the past few weeks, I have been experimenting with high-performance web applications using JavaScript, and one of the problems I’ve experienced is throttling my app based on client-side performance in real-time. My development machine has decent hardware, but what about phones? Or older computers?

To solve this issue, I considered the way a gearbox or transmission in a car works: given some threshold (RPMs in the case of cars), change gears to maintain performance. Instead of RPMs, I have a timing loop that runs at some interval. I then compare how long it actually took before the loop ran. Given that information, we can approximate how clogged JavaScript’s queue is, and adjust our app accordingly.

To do this, once the “delay” reaches a certain threshold, we simply change gears. What does this mean for the application? The simple answer: provide less intensive implementations based on the current gear. For instance, if your site has a lot of animations and the client’s browser can’t handle it, turn off more animations the higher the gear number is. That way, your app will tune itself to the client machine’s performance capabilities automatically. Here’s a link to the project:

[Gearbox.js on Github]

Tutorial: Intro to jQuery

My wife was on her Facebook the other evening when she stumbled on a post from a friend of hers from High School: “I give the &*#$ up…” The friend was in a class about JavaScript and jQuery, and with the end of the semester closing in was struggling. She was willing to learn, but hadn’t been given the proper instruction so that the pieces made sense together. So, I spent some time online with her helping her understand how to use these tools to get the job done, and along the way I discovered some teaching strategies and examples that worked and some that didn’t. I took what I told her, cleaned it up, and produced a little online tutorial for getting started with jQuery. Go ahead and check it out here:

[Open Tutorial]

Cheers!

Steven

Coding Around the Problem

mainframe codeLate last year, I was working on a piece of code that was quite troublesome: I had a variable that was changing its value for absolutely no reason! I spent two days trying to explain how that value could possibly be changing, and got nowhere. The worst part: the program in question touched every record in the database when it ran, and if the value changed during the running of the program, records got orphaned.

The code in question started off as a mainframe application, but now it was C# code running against a SQL database and THERE’S NO WAY THAT VARIABLE CAN CHANGE. However, the vendor who built the ORM used unsafe pointers and GOTOs, so who knows… The other scary part is that the intended purpose of the program was to alter record keys, which is why it had to iterate over all of the tables in the database. For whatever reason, the value would reset to its original value after having updated about 20% of the tables and orphan all related table records from that point on. Needless to say that our customer was not thrilled with the outcome of the program since it hosed their data.

After bashing my head against a desk for several more days, I talked to the senior project manager about it. Having been a coder himself at one point and considering his generally “out of the box” thinking, he says to me “Why don’t you store the value in another variable, then when you get to the part of the program where the value changes, set it back to what it was supposed to be.” I said, “THAT’S CRAZY!” Well, I tried it and it worked. In the end, we ended up blocking the program so that people weren’t changing database keys to begin with, which is probably for the best. However, it was an interesting experience in programming the right way, getting the job done, and knowing when to change course.

First Post!

So, I finally got a smartphone, a twitter, and now a blog which means I will be participating as part of the “Internet community” or whatever you want to call it. I will mostly be posting programming-related stuff, but sometimes I write about space policy, science, food, and maybe football.

Cheers!

Steven