mkdir js-this && cd js-this
mkdir src
touch src/index.js index.html
code .
In this lecture we will talk special value this
and explain 5 rules it has.
this
is a special keyword value that JavaScript automatically creates in the scope of every function.
Once a function
is called and it executes, this
is created inside of the scope of that function.
It is a misconception that this
is used in the objects. Wrong!
In JavaScript this
is used in the funcitons and it's sole purpose is to be used in the functions to enable the reusability of the function.
this
is one of the most misunderstood mechanisms in Javascript. Many JavaScript developers don't fully understand how this
works and why it is even used.
However, this
mechanism has few simple rules that we will learn in the following steps.
Understanding this
special keyword value is an important foundational concept used in many areas of JavaScript.
After learning how this
works in JavaScript you will be able to:
- Use
this
effectively in functions and arrow functions - Use functions properly as methods in OOP.
- Be able to answer common interview question when asked about
this
and solve related interview challenges. - Successfully handle callbacks of DOM event listeners,
setTimeout
andsetInterval
. - Better understand code of other developers such as one found in libraries, packages, frameworks.
A common interview question for junior developers is, that I would like you to answer now in our slack channel:
Q:
Where is `this` always used in JavaScript ?
A:
`this` is always used in functions.
If the new keyword is used when calling the class
or a function
, this
inside the function is a brand new object.
function Car (brand, model) {
console.log(this); // ==> {}
}
new Car(); // {}
What happens behind the scene is that value this
holds the new empty object instantiated by the class to which the properties are added. At the end constructor returns the newly created object.
function Car (brand, model) {
// this = {}
console.log(this);
this.brand = brand;
this.model = model;
console.log(this); // this = { brand: '...', model: ''}
// return this
}
const carObj = new Car();
If a function is being invoked as a standalone funciton (without an object on the left side), then this
inside of that function refers to the global
object Window
(or undefined
if in strict mode).
function whatIsThis () {
console.log(this);
}
whatIsThis();
this
keyword in the method holds the value of whatever is on the left of the dot at the time of invocation (the object that is invoking the method).
Question
const person1 = {
name: 'John',
age: 30,
printThis: function () {
console.log('one', this);
},
address: {
country: 'Scotland',
city: 'Glasgow',
printThis: function () {
console.log('two', this);
},
}
};
// What is this in the `person.printThis` ?
person1.printThis();
// What is this in the `person.address.printThis` ?
person1.address.printThis();
If the function/method is an ES2015 arrow function, it receives this
value of its surrounding scope at the time it is created.
const person2 = {
name: 'Alberto',
age: 41,
regularMethod: function () {
console.log('regularMethod this', this)
const arrowFunc = () => console.log('arrowFunc this', this);
arrowFunc();
// arrow function will borrow `this` value from the surrounding scope
// of `regularMethod` where it was created
},
};
person.regularMethod();
Certain built-in JavaScript functions and interfaces cause the loss of this
value in the functions.
These are setTimeout
/setInterval
, event listeners and loop methods forEach
/map
/filter
.
class Clock {
constructor() {
this.time = 0;
this.tickRegular = function () {
this.time += 1;
console.log(this.time);
};
}
};
const clockA = new Clock();
setInterval( clockA.tickRegular, 1000 ); //
In the above example setInterval
is continuously invoking the method tickRegular
every 1s ( 1000 milliseconds ).
However the this
value in the tickRegular
is lost as method is called as a callback by the browser's function setInterval
.
One common technique to prevent the loss of this
in when using the above mentioned built-in functions is to use arrow functions or arrow methods. Let's see how we can fix the above problem by using an arrow method instead:
class BetterClock {
constructor() {
this.time = 0;
this.tickArrow = () => {
this.time += 1;
console.log(this.time);
}
}
};
const clockB = new BetterClock();
setInterval( clockB.tickRegular, 1000 ); //
We can see that arrow function takes the value of this
from the scope in which it was created, from the constructor, where this
represents the new object instance.
Methods call()
, apply()
or bind()
can explicity set the value of this
inside of a function.
These methods can only be used with regular funciton
and can not be used for arrow funcitons.
function printThis() {
console.log(this);
}
const office = {
address: 'C. Pamplona 96',
color: 'gray'
}
const school = {
address: '120 SW 8th St',
color: 'white'
}
printThis(); // --> Window
printThis.call(office); // --> office { address: "C. Pamplona 96", color: "gray" }
printThis.call(office); // --> school { address: "120 SW 8th St", color: "white" }
bind()
method is used to create a new function with a permanently set (bound) this
value.
Method bind()
creates a copy out of an existing function and sets this
to the provided value.
const car = {
brand: 'Tesla',
model: 'S',
details: function () {
console.log(`${this.brand} ${this.model}`);
}
}
car.details(); // --> Tesla S
const macPro15 = {
brand: 'Apple',
model: 'MacBook Pro 15'
}
// Create a new function and bind `this` to object `macPro15`
const boundDetails = car.details.bind(macPro15);
boundDetails(); // --> Apple MacBook Pro 15
boundDetails(); // --> Apple MacBook Pro 15
// new function `boundDetails` has `this`
// permanently bound to object `macPro15`
Let's take 5 minutes to recall 5 rules of this
and how the value changes.
Let's all write them down in Slack and then when ready post your answer in the general channel.
To begin with I will provide you with the first rule:
**Q:**
What are 5 rules where this in a function changes ?
1. In `class` when using keyword `new`... the value of `this` is the new object instance.
2. In a standalone function, the value of `this` is...
A:
2. In a standalone function, the value of `this` is the global object (Window)
3. In function methods, the value of `this` is object on the left of the dot at the time of inovcation
4. Arrow functions don't have `this` binding, but they borrow `this` from the scope in which they are created.
5. Using call(), apply() or bind() we can change the value of `this` in a function.
-
Calling a function without a leading parent object will get you the value of
this
as theglobal
/window
-
In a method function which is a method,
this
points to whatever is -> On the left of the dot at the time of invocation (calling the function). -
When using keyword
new
with a constructor,this
represents a newly created object. -
Arrow functions do not bind it's own
this
, but they takethis
from the surrounding scope where they were created. -
We use
call
,apply
orbind
to change thethis
value of a function.