If you have been learning JavaScript you might have come across the keyword this
and wondered what it does and most importantly how it works. the most simple answer to that question is " this
refers to an already declared property in the scope of where it is being used", but even that can be slightly misleading when trying to fully understand this
. so that is why this dev post exists, to get you understanding how to use this
and become a better developer by the end.
The way this interacts with objects
Open your Chrome Developer console
(windows: ctrl + shift + j)
(mac: cmd + option + j)
and type the following
console.log(this);
This should have returned the global window object. The global window object is the Global object in the browser. this is also where all our variables are stored (not const), but the reason that the window object is returned is because this
is being used outside of a declared object. so lets see an example with one.
let cereal_bot = {
cereal: "Frosted flakes"
milk: "2% milk"
make_bowl: function() {
console.log(`${this.milk} + ${this.cereal} = cereal and milk`)
}
}
console.log(cereal_bot.make_bowl)
// returns => 2% milk + Frosted Flakes = cereal and milk
In the code above I declare an object and use the this
method inside the function to use some of the values in the object. this happens because the value of this
is set to the closest parent object the method is called on. meaning that if we have nested objects with the same propertys like the one below,
let cereal_bot = { // outer object
cereal: "Frosted flakes",
milk: "2% milk",
make_bowl: function() {
console.log(`${this.milk} + ${this.cereal} = cereal and milk`)
},
cereal_bot2: { // inner object
milk: "almond milk",
cereal: "coco puffs",
topping: "berries",
make_bowl: function() {
console.log(`${this.milk} + ${this.cereal} + ${this.topping} = cereal and milk with ${this.topping}`)
}
}
}
console.log(cereal_bot.make_bowl)
=> "2% milk + Frosted Flakes = cereal and milk"
console.log(cereal_bot.cereal_bot2.make_bowl)
=> "almond milk + coco puffs + berries = cereal and milk with berries
this
will correctly correspond with the object its being used by. cereal_bot still logs the correct values
assigned to this
, and our new cereal_bot2 uses its own object values without any issue even though the property's have the same name, this is another reason this
is a helpful tool to use
The way this interacts with Constructors
Constructor functions in JavaScript are used to create a multitude of objects with slight variations between them like the one below.
//constructor parent
function Human (first, last, age, talent) {
this.first = firstName,
this.last = lastName,
this.age = age,
this.talent = function(talent) {
return console.log(`I am talented at ${talent}`)
}
}
//child of constructor function
let charlie = new Human('Charlie', 'Day', 46, 'actor)
let rob = new Human('Rob', 'McElhanney', 45, 'actor)
let glenn = new Human('Glenn', 'Howerton', 46, actor)
console.log(charlie)
logs => {
first: 'Charlie',
last: 'Day',
age: 46,
talent: function(talent) {
return console.log(talent)
}
The constructor function above is what we use to make our new human objects. when the this
keyword is used in a constructor function it is bound to the new object being created.
The way this works with call,apply,bind
call()
, apply()
, and bind()
all allow us to explicitly set the value of this in one way or another. They are all somewhat similar but its important to understand the differences.
call and apply are invoked immediately, while bind returns a function with the context of this bound already. this is useful when we don't know all our arguments up front. but an example will make it more clear.
Call
When we use call the first parameters is what this
is bound to.
the subsequent parameters are passed to the function we are calling.
function add(c, d) {
console.log(this.a + this.b + c + d}
let obj = {a: 1, b: 2};
//function, this, argument, more arguments?
add.call(obj, 4, 3)
// logs => 10
Apply
apply is similar to call where the first parameter is what this
is bound to but the subsequent parameters is an array of arguments to be used in the function being called.
You can even use apply to concatenate arrays.
function add(c, d) {
console.log(this.a + this.b + c + d}
let obj = {a: 1, b: 2};
add.apply(obj, [3,4])
// logs => 10
let arr1 = [1, 2];
let arr2 = ['a', 'v'];
arr1.push.apply(arr1, arr2);
console.log(arr1) // logs => [1, 2, 'a', 'v']
Bind
bind's parameters are identical to call but bind is not invoked immediately. instead bind returns a function with the context of this
bound already. Bind is best used when we don't know all our arguments.
let object = {
a: 1,
func: function(b, c, d) {
console.log(this.a+b+c+d);
}
}
let increase = {
a: 100
}
let binding = object.go.bind(increase,2);
console.log(binding) logs =>
function(b,c,d) {console.log(this.a+b+c+d)
}
In Conclusion
This
is a hard to understand concept in JavaScript that is very specific to the context its being used in, but I hope that this dev-post made it a bit more clear on when/how to use this
and in what context. but if you are still unsure just remember these few things
the value of
this
is usually determined by a functions contextin the global scope,
this
refers to the global window objectwhen a construction is used
this
is bound to the new object being createdyou can set the value of this using call,bind,apply
google and continue to read articles on what you don't understand
Thank you for reading this dev-post and I hope my post helps you in your programming career. - Sidney :)
Top comments (0)