What is “this” in Javascript

RM
3 min readFeb 15, 2018

--

What is “this” in Javascript — especially, when you use bind( ), arrow function and regular function?

this refers to its closest object.

If this is called in a global scope, then this refers to window object in a browser or global object in Node.

function checkThis() {
return this;
}
// In a browser:
checkThis() === window; // true
// In Node:
checkThis() === global; // true

But what other things that could be inside this ?

The answer is, well … whatever the object is.

this is but an alias to the actual object. See below, this is equivalent to user.

let user = {
name: "Maya",
age: 30,
callMe() {
alert(this.name);
alert(user.name);
}
};user.callMe(); // will output "Maya", and then "Maya" again

That’s it?

Wait, there is more!

this is defined or evaluated during run-time. The moment you create or write this, this is just a concept or a keyword in the ocean of your codebase (that you expect to work and mean something, of course). But only when the function runs, this will turn into an object (or undefined, when there is no object in its outer scope and when the code is set to be in a strict mode).

let human = { name: "Maya" };
let dog = { name: "Pillow" };
function sayHi() {
alert( this.name );
}
// assign the function into two objects
human.sayHi = sayHi;
dog.sayHi = sayHi;

When we call sayHi() on two different objects (human and dog), this has different objects each time.

this inside the following function is the object “before the dot”

human.sayHi(); // Maya  (this == human)

this inside the following function call is the object “before the opening bracket”

dog['sayHi'](); // Pillow  (this == dog)

*Both function call styles work just the same.

So the meaning of this just relies on the scope, its closest object and the run-time of our function then?

Not necessarily. Especially if that is not what you want.

We can actually decide what this should be!

How?

We can tie our this to whatever object we pass in to our bind().

Let’s see two examples of similar code with different names addThis() and noThis(), both run console.log(this);

function addThis() {
console.log(this) // 'this' = "hello" because it is bound to "hello"
}
function noThis() {
console.log(this); // 'this' = window object
}
let runMe = addThis.bind("hello"); // ties "hello" to addThisrunMe(); // executes addThis and returns "hello" noThis(); // executes noThis and returns a window object

But what about a function that lives inside a function that is already bound to an object?

Will that inner function inherit the bound object of its parent’s function?

The answers are : YES AND NO.

Yes, if the inner function is an arrow function.

Because this type of function does not have its own this, but will latch on to any object that its parent is bound to (a window object if the arrow lives in the global scope).

No, if the inner function is a function that uses function keyword.

Because, this type of function, will lose its binding / object context and back to be to tied to the window object again.

function parentFunc() {  console.log(this) // 'this' = "hello"

childFuncArrow = () => {
console.log(this); // 'this' = "hello"
};
childFuncArrow();

function childFuncNormal() {
console.log(this); // 'this' = the window object - oh no!
}
childFuncNormal();

}
let runMe = parentFunc.bind("hello"); runMe(); // execute parentFunc which outputs "hello", "hello", Window object

Even if we don’t use bind(), inner arrow function will always take its this from the nearest object - which in this case is bound to the arrow function by its normal function parent, the twoFunctions(). But inner normal function will lose its context.

The example below, shows an arrow function’s this as the human object (its direct parent’s this) and the normal function will return undefined.

let human = {  name: "Maya",

twoFunctions() {
console.log(this.name); // output "Maya" let arrow = () => console.log(this.name); // output "Maya" arrow();

function notArrow() {
console.log(this.name); // output "undefined" - because it tries to call window.name
}

notArrow();
},
}

human.twoFunctions(); // Will output "Maya", "Maya" and "undefined"

--

--

RM

Software engineer with master’s degrees in Computer Science and Politics. Passionate about animals, software accessibility and UI/UX design.