JavaScript for the C# Guy: The confusion about 'this'


As a C# guy I am comfortable with the idea of 'this' in the scope of a class (or 'Me' for your VB'ers). It's a relatively simple idea that allows you to access the instance of the class that you're a part of to call members.

In JavaScript that have a similar idea but because of the nature of JavaScript it can cause some odd behavior. Let's look at the standard behavior first.

If we have global code (outside objects or functions) and check the 'this' object, it usually returns the "Window" object in the DOM:

<script type="text/javascript">
  console.log(this.toString()); // Window
                                // unless in strict mode: undefined
</script>

The reason I say that the 'this' keyword returns the "Window" usually is that if you are using strict mode (introduced in ECMA Script 5), then the this keyword is supposed to return undefined. But let's ask the more interesting question, why does this return the "Window" object?

The "Window" object is returned because in the browser, the Window object implements the global object. You can think of the "Window" as implementing the global interface (that's as close as I can map it to C#isms). It has more functionality than just the global objects (e.g. data about the Window) but is a proxy to the global scope.

This behavior changes when you create an object using object syntax in JavaScript:

var obj = {
  name: "hello",

  getThis: function () {
    console.log(this.toString()); // [object object] name = "hello"
    return name;
  } 

};

In this case the 'this' is usually the object itself. Again...that usually word. If you were to have access to the object and call the function, then the 'this' keyword would in fact be the object:

var obj = {
  name: "hello",
  getThis: function () {
    console.log(this.toString()); // [object object] name = "hello"
    return name;
  } 
};
obj.getThis();

This works because the context of the getThis function is the obj object. But since functions are just object types in JavaScript, you can change the scope accidently pretty easily. For example:

var obj = {
  name: "hello",
  getThis: function () {
    console.log(this.toString()); 
    return name;
  }
};
var someFunc = obj.getThis;
someFunc();  // this becomes Window

This happens because the scope of the someFunc function becomes the global scope. It is no longer being executed in the scope of the object. This happens for JavaScript pseudo-classes too:

function MyClass() {
  this.name = "MyClass";
  this.showMe = function () {
    console.log(this.toString()); // [object MyClass]
  };

  return this;
};

var my = new MyClass();
my.showMe(); // this is [object MyClass]

Just like before, when showMe is called, the context of the function is the pseudo-class therefore the 'this' object returns the instance of the MyClass object. But also like before, if you assign the function to a local variable, it executes in a different context:

function MyClass() {
  this.name = "MyClass";
  this.showMe = function () {
    console.log(this.toString()); // [object MyClass]
  };

  return this;
};

var my = new MyClass();

var myFunc = my.showMe;
myFunc(); // 'this' is Window

But we can avoid this behavior with a small piece of code. While creating the pseudo-class our 'this' object is the instance of the class so we can ensure that the function always executes in the context of the instance by binding it to the function:

function MyClass() {
  this.name = "MyClass";
  this.showMe = function () {
    console.log(this.toString()); // [object MyClass]
  }.bind(this);

  return this;
};

var my = new MyClass();

var myFunc = my.showMe;
myFunc(); // 'this' now is [object MyClass]

Whew!  Questions?


Bootstrap 4 is Here!

After a long development cycle, Bootstrap has been completely re-written to improve performance and be more consistent. Learn Bootstrap 4 now with my Wilder Minds course:

Enroll Today


Shawn
Shawn Wildermuth
Author, Teacher, and Coach




My Courses

Wilder Minds Training
Vue.js by Example (Now Available)
Bootstrap 4 by Example
Intro to Font Awesome 5 (Free Course)
Building a Web App with ASP.NET Core, MVC6, EF Core, Bootstrap and Angular (updated for 2.1)
Using Visual Studio Code for ASP.NET Core Projects
Implementing ASP.NET Web API
Web API Design
JavaScript for C# Developers

Application Name WilderBlog Environment Name Production
Application Ver v4.0.30319 Runtime Framework x86
App Path D:\home\site\wwwroot\ Runtime Version .NET Core 4.6.26814.03
Operating System Microsoft Windows 10.0.14393 Runtime Arch X86