The JavaScript “this” Keyword Deep Dive: Constructor Functions

JavaScript

JavaScript LogoLearn how the JavaScript “this” keyword differs when instantiating a constructor (as opposed to executing the function).

In earlier articles of the “The JavaScript “this” Keyword Deep Dive” series, we discussed how the meaning of “this” differs in various scenarios. In this article, we will focus on JavaScript constructors. It is critical to keep in mind that in JavaScript, constructor functions act like classes. They allow you to define an object that could exist. The constructor itself is not yet an object. When we instantiate that constructor, the return value of the instantiation will be an object, and in that object, “this” refers to the instance object itself.

So, inside of a constructor function, the JavaScript keyword refers to the object that will be created when that constructor is instantiated.

Example # 1

In Example #1, you’ll see that we have created two new properties of the window object: “music” and “getMusic”. The “window.getMusic” method returns the value of window.music, but it does so by referencing: “this.music”. Since the “window.getMusic” method is executed in the global context, the JavaScript “this” keyword refers to the window object, which is why window.getMusic returns “classical”.

When you instantiate a JavaScript constructor function, the JavaScript “this” keyword refers to the instance of the constructor.

We’ve also created a constructor function named “Foo”. When we instantiate Foo, we assign that instantiation to the variable: “bar”. In other words, the variable “bar” becomes an instance of “Foo”. This is a very important point.

When you instantiate a JavaScript constructor function, the JavaScript “this” keyword refers to the instance of the constructor. If you remember from previous articles, constructor functions act like classes, allowing you to define a “blueprint” object, and then create “instances” of that “class”. The “instances” are JavaScript objects, but they differ from object literals in a few ways.

For an in-depth discussion of the difference between an object literal and an instance object, see the article: “What is the difference between an Object Literal and an Instance Object in JavaScript? | Kevin Chisholm – Blog”.

Earlier on, we established that inside a function that is not a method, the JavaScript “this” keyword refers to the window object. If you truly want to understand constructor functions, it is important to remember how the JavaScript “this” keyword differs inside that constructor. When you look at the code, it seems as if “this” will refer to the window object. If we were to simply execute Foo as if it were a normal function, this would be true (and we will discuss this scenario in Example # 3). But we don’t simply execute Foo; we instantiate it: var bar = new Foo().

When you instantiate a JavaScript constructor function, an object is returned. The JavaScript “this” keyword has a special meaning inside of that object: it refers to itself. In other words, when you create your constructor function, you can use the “this” keyword to reference the object that WILL be created when the constructor is instantiated.

So, in Example # 1, the getMusic method returns “this.music”. Since the “music” property of Foo is: “jazz”, then the getMethod returns “jazz”. When we instantiate Foo, the variable “bar” becomes an instance of Foo, so bar.getMusic() returns “jazz”.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 1: http://jsfiddle.net/2RFa3/

Example # 2

In Example # 2, we have changed Foo’s “GetMusic” method. Instead of returning “this.music”, it returns an executed function. While at first glance, it may seem as though the “getMusic” method will return “jazz”, the JSFiddle.net link demonstrates that this is not the case.

Inside of the “getMusic” method, we have defined a variable that is equal to an anonymous function: “myFunction”. Here is where things get a bit tricky: “myFunction” is not a method. So, inside that function, the JavaScript “this” keyword refers to the window object. As a result, that function returns “classical” because inside of “myFunction”, this.music is the same thing as window.music, and window.music is “classical”.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 2: http://jsfiddle.net/2RFa3/1/

Example # 3

In Example # 3, we have an example of a scenario that you don’t want: executing a JavaScript constructor function instead of instantiating it. Hopefully, this is a mistake that you will catch quickly, but it can happen. It is also possible that you might inherit code that contains such a bug. Either way, this is bad.

While the Foo constructor still has a “getMusic” method, because we execute Foo, instead of instantiating it, the code inside of Foo overwrites two properties that we created earlier: window.music and window.getMusic. As a result, when we output the value of “this.getMusic()”, we get “jazz”, because when we executed Foo, we overwrote window.music, changing it from “classical” to “jazz”.

While this is a pattern that you want to be sure to avoid in your code, it is important that you be able to spot it. This kind of bug can leave you pulling your hair out for hours.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 3: http://jsfiddle.net/2RFa3/2/

Summary

In this article we learned how the JavaScript “this” keyword behaves in a constructor function. We learned about instantiating a constructor and the relationship between “this” and the instance object. We also discussed a couple of scenarios that are important to understand with regards to “this” and constructor functions.

The JavaScript “this” Keyword Deep Dive: Nested Methods

JavaScript

JavaScript LogoDepending on the scenario, the JavaScript “this” keyword may refer to the object of which the method is a property, or the window object.

In an earlier article: The JavaScript “this” Keyword Deep Dive: Nested Functions, we learned how functions that are not methods evaluate “this” to the window object. In that post, we demonstrated that no matter how deeply you nest functions, this behavior is always the same. In this article, we will learn how the JavaScript “this” keyword behaves in nested methods.

So, here, it might be a good idea to quickly answer the question: “What is a nested-method”?

A method is a function that is a property of an object. A nested method occurs when a method, in turn, returns an executed method.

The reason that this scenario is an important one to consider is that while you may execute method A, if that method returns the executed method of object B, then inside of that second method, the JavaScript “this” keyword refers to object B (not object A).

Example # 1

In Example # 1, we have added a property to the window object named “music”, and set the value to: “classical”. We have also added a method to the window object named “getMusic”, which returns the value of window.music. But, notice that instead of referencing window.music, the method returns: this.music. The reason that works is that since the method is a property of the window object, “this” refers to the window object. This means that this.music is the same thing as this.music, and the value of that property is: “classical”.

We have also created an object named “foo”, and it has the exact same-named properties we specified above, and the “getMusic” method has the exact same code: return this.music. But foo’s “getMusic” method returns “jazz”, because foo.music = “jazz”, which means that inside of foo’s “getMusic” method, the JavaScript “this” keyword refers to the foo object, and foo.music is “jazz”.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 1: http://jsfiddle.net/5uUJ8/

Example # 2

In Example # 2, we have created an object named: “foo”, which has a method named: “getMusic”. The getMusic method returns an object with two properties: “music”, which is equal to “rock”, and “getMusic” which returns this object’s “music” property.

When we pass the output of foo.getMusic() to the console, we see that is: “rock”, and now “Jazz”. The reason for this is that foo’s getMusic method ignores foo’s music property. That is, it returns an object, and that object’s getMusic method returns its own “music” property. In this scenario, we have nested a method: foo.getMusic, that returns the executed method of another object. The reason for this example is to demonstrate the fact that even though foo.getMusic returns a nested method, when the nested method utilizes the JavaScript “this” keyword, it refers to the object that it is a property of, not foo.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 2: http://jsfiddle.net/5uUJ8/1/

Example # 3

So, in Example # 3, we take the exact same approach as Example # 2, providing an additional level of method-nesting. As you might expect, the innermost method returns “metal”, the value of the “music” property to which the getMusic method belongs.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 3: http://jsfiddle.net/5uUJ8/2/

Example # 4

Example # 4 is somewhat similar to Example # 3, except that the nesting is logical, not physical: each getMusic method, in turn, calls the getMusic method of a different object. The end result is the same as Example # 3: “metal”. But instead of one method returning an anonymous object whose getMusic method is executed, each of the getMusic method calls here return the execution of another named-object’s “getMusic” method.

It is also important to note that the first console.log call: this.getMusic returns “classical”, because the window.getMusic method is a property of the window object. But, each of the other objects (i.e. “rockObject” and “metalObject”) have its own “music” properties, so when the “metalObject.getMusic” is called, it returns the value of metalObject’s “music” property, which is “metal”.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 4: http://jsfiddle.net/5uUJ8/3/

Summary

In this article we discussed how the JavaScript “this” keyword behaves inside of nested methods. We learned what a nested method is. And we also learned how, in this scenario, the JavaScript “this” keyword refers to the object of which the method is a property, not the window object.

The JavaScript “this” Keyword Deep Dive: Nested Functions

JavaScript

JavaScript LogoLearn how the JavaScript “this” keyword behaves inside of function declarations and expressions, even when nested 10 levels deep.

In the article: The JavaScript “this” Keyword Deep Dive: An Overview, we discussed a number of scenarios in which the JavaScript “this” Keyword has different meanings. In this article, we will concentrate on functions and methods.

It’s important to note that methods are functions. What makes a method a method is that the consumer of the code specifies an object, and then calls a method of that object.

Example # 1

In Example # 1, we have executed a function and a method. We have actually executed two functions, but the second function: “someMethod” is actually a method of the “bar” object. We know this because we have used the syntax: object.method().

It’s important to understand the difference between executing a function and a method.

Example # 2

foo = function (){ return this.music; }; console.log(this.music); //’classical’ (global) console.log(foo()); //’classical’ (global)

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 2: http://jsfiddle.net/84Yd4/

In Example # 2, we have executed the function “foo”, which returns the value of “this.music”: “classical”. Both console.log statements return the value: “classical”, because since we are not inside of a method, the JavaScript “this” keyword refers to the window object, and at the top of the code, you’ll see that window.music is equal to “classical”.

Example # 3

foo = function (){ function bar(){ function baz(){ function bif(){ return this.music; } return bif(); } return baz(); } return bar(); }; console.log(this.music); //’classical’ (global) console.log(foo()); //’classical’ (global)

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 2: http://jsfiddle.net/84Yd4/1/

In Example # 3, things get a bit silly, but the effect is the same. Even inside of nested functions, because none of these functions are methods, the JavaScript “this” keyword refers to the window object. And “this.music” is the same as “window.music”, which is equal to “classical”.

Example # 4

foo = function (){ function bar(){ function baz(){ function bif(){ function billy(){ function bobby(){ function betty(){ function jetty(){ function jimmy(){ function judy(){ return this.music; } return judy(); } return jimmy(); } return jetty(); } return betty(); } return bobby(); } return billy(); } return bif(); } return baz(); } return bar(); }; console.log(this.music); //’classical’ (global) console.log(foo()); //’classical’ (global)

In Example # 4, the function-nesting concept is taken to a ridiculous level. Nonetheless, the output is exactly the same: “this.music” is the same as “window.music”, which is equal to “classical”. It does not matter how deeply a function is nested. Unless it is a method of an object, the JavaScript “this” keyword will always refer to the window object.

HERE IS THE JS-FIDDLE.NET LINK FOR EXAMPLE # 3: http://jsfiddle.net/84Yd4/2/

Summary

In this article we learned that when a function is not specified as a method of an object, the JavaScript “this” keyword refers to the window object. This is true even in the case of nested functions. In fact, no matter how many levels deep we nest functions, the JavaScript “this” keyword refers to the window object.

Understanding Context in JavaScript – Object Literals

JavaScript

JavaScript Logo - context

Why is the word “this” so important in JavaScript?

In the post: “Understanding Scope in JavaScript,” I covered the basics of how scope works when dealing with functions. Sometimes the words “scope” and “context” are used interchangeably, which only leads to confusion because they are not the same thing.

In JavaScript, “context” refers to an object. Within an object, the keyword “this” refers to that object (i.e. “self”), and provides an interface to the properties and methods that are members of that object. When a function is executed, the keyword “this” refers to the object that the function is executed in.

Here are a few scenarios:

So, as you can see, “this” can easily give you a headache. But hang in there; we are getting to the good stuff now.

In a nutshell, in Object-literals, you don’t have local variables; you have properties of the object. So, where inside of the function foo() I might say “var drink = ‘beer’; “, for an object literal called “bar”, I would say “bar.dink = ‘beer’. “ The difference is that “beer” is a property of “bar”, whereas when a function is executing, a local variable is defined by the “var” keyword and cannot be seen by anyone or anything outside of the function.

Example # 1

Here is the jsFiddle.net link for Example # 1: http://jsfiddle.net/Q9RJv/

In Example # 1, we first create a global variable named “drink”, and set it equal to “wine”. We’ll come back to that in a minute.

Next, we create an Object Literal named “foo”, with a property “drink” that is equal to “beer”. There is also a method that simply returns “drink”. But why does it return “wine”, and not “beer”? This is because in the object “foo”, “drink” is a property of foo, not a variable. Inside of functions, when reference is made to a variable, the JavaScript engine searches the scope chain and returns the first match it finds.

Although this function executes in the context of “foo”, “foo” does not have a variable named “drink”. It has a property named “drink”, but not a variable. So the JavaScript engine searches the next level of the scope chain. The next level of the scope chain is the global object, which contains a variable named “drink”, so the value of that variable (“wine”), is returned.

But wait a minute Kevin, how can we make reference to the property “drink” that is in the context of the object “foo”?

I’m glad you asked.

Example # 2

Here is the jsFiddle.net link for Example # 2: http://jsfiddle.net/HGM93/

In Example # 2, the only change we have made is that in the anonymous function that is assigned to “getDrink”, we return “this.drink” instead of “drink

This is an important detail. When a function executes in the context of an object , the keyword “this” refers to that object. You can access any of the properties of the object by using the “this” keyword, add new ones (e.g. this.color = “blue”), and change existing ones (e.g. this.drink = “juice).

Using Dot Notation to Create a JavaScript Object Literal

Example # 3

Here is the jsFiddle.net link for Example # 3: http://jsfiddle.net/ZA77k/

In Example # 3, we have the exact same functionality as Example # 2. From the JavaScript engine’s perspective, we have achieved the same goal, and the console output is exactly the same.

The difference is how we organized our code. In Example # 2, we created the properties “drink” and “getDrink” at the exact same time that we created the object literal “foo”. It is all one expression. In Example # 3, we create an empty object named “foo” first, and then use dot notation to add properties to the object one-by-one. I just wanted to point out that there is more than one way to go about all of this from a syntax perspective.

Object Literals Can Contain Other Object Literals, and those Objects Have Their Own Context

Example # 4

Here is the jsFiddle.net link for Example # 4: http://jsfiddle.net/8p38y/

In Example # 4, we have added a new property to “foo”, and that property is yet another object. At first it is empty (i.e. foo.under21 = {}), and then we add two properties to it. The first property is “drink”, which is set equal to “soda”. Don’t’ confuse this with the property “drink” that is set in the context of “foo” which is equal to “beer”. In the context of “foo.under21”, “drink” is equal to “soda”.

The second property of “foo.under21” has an anonymous function assigned to it. That anonymous function returns “this.drink”. In the context of “foo.under21”, “drink” is equal to “soda”, so calling that function returns “soda”.

So the point of this example is that object literals can have properties that are themselves objects, and those objects have their own context. When functions execute in the context of those objects “this” refers to the object, and so on. I am aware of no limit to this kind of object nesting.

The JavaScript .call() and .apply() Methods Allow You to Dynamically Change the Context In Which a Function is Executed

Example # 5

Here is the jsFiddle.net link for Example # 5: http://jsfiddle.net/A5ydt/

Ok, so here is the bonus question: In Example # 5, why does a call to “foo.under21.getDrink()” now return “wine” ?

This is because we changed the inner-workings of that function. Instead of simply returning “this.drink”, we use the JavaScript “.call()” method, which allows you to execute any function in the context of another object. When you do not specify the context in which that function is to be “called”, it executes in the context of the global object. In the global context, there is a variable named “drink” and it is equal to “wine”, so “wine” is returned.

Example # 6:

Here is the jsFiddle.net link for Example # 6: http://jsfiddle.net/cS4cv/

In Example # 6, “soda” is returned because when we used the JavaScript “.call()” method, we specified the context in which the function is to execute. In this case, the context we specify is “this”. “this” refers to the context of “foo.under21”, and “foo.under21” has a property named “drink”, so the value “soda” is returned.

Summary

The last two examples may seem like overkill, but I wanted to point out that just when you start to get a handle on the concept of context in JavaScript object literals, you must realize that there is a bit more to consider. JavaScript Object Literals can have properties that are also objects, and those objects have their own context.

In each case, when a function executes within that context, inside of the function, the “this” keyword refers to the object that the function is a property of, because the function executes in the context of that object. By using the JavaScript “.call()” method (or “.apply()” method), you can programmatically change the context in which that function executes, which changes the meaning of the “this” accordingly.