This keyword concept :
- this keyword refers to an object, that object which is executing the current bit of javascript code.
- In other words, every javascript function while executing has a reference to its current execution context, called this. Execution context means here is how the function is called.
- To understand this keyword, only we need to know how, when and from where the function is called, does not matter how and where function is declared or defined.
case : Global scope
console.log(this) // refers to the global object
case : II
const sum = () => {
// incase of regular function as well it
points to global object
let a = 122;
console.log(this)
}
sum();
foreg:
var myvar = 100;
function whoisthis() {
const myvar = 200;
console.log(myvar); //200
console.log(this.myvar); ------> window.myvar
// 100
}
whoisthis();
case : III
Implicit Binding of this:
"when there is an object property which we are calling as
a method then that object becomes this object
or execution context object for that method,
it is implicit binding of this keyword."
// This keyword with object
let mobile = {
brand: 'smsung',
price: '1200',
warranty: '2yrs',
calprice: function() {
console.log(this);
console.log(this.brand)
}
}
mobile.calprice()
case : IV
Default binding of “this”
"If we are in strict mode then the default value of
this keyword is undefined otherwise this keyword act
as global object, it’s called default binding of
this keyword.(default is window object in case of browser)."
"use strict"
// undefined because it donot know which object
this keyword it is pointing to
function sum() {
console.log(this)
}
sum();
Foreg :
function bike() {
console.log(this.name);
}
const name = "Ninja";
const obj1 = { name: "Pulsar", bike: bike };
const obj2 = { name: "Gixxer", bike: bike };
bike(); // "Ninja"
obj1.bike(); // "Pulsar"
obj2.bike(); // "Gixxer"
- In the above code snippet, the job of
bike() function is printing the this.name which means it’s trying to print the value of name property of the current execution context(i.e.this object). - In the above code snippet, when function
bike() gets called it prints “Ninja” because the context of execution is not specified so by default its global context and there is a variable name is present at global context whose value is “Ninja”.
- In case of
obj1().bike(), “Pulsar” gets printed and the reason behind this is function bike() gets called with the execution context as obj1 so this.name became obj1.name . Same with obj2.bike() where the execution context of function bike() is obj2.
THIS KEYWORD WITH ARROW FUNCTION:
As in my days , beginner i just used to wrap my head around ES2015 syntax.
"I began using arrow functions everywhere without really understanding how they worked. As you might expect, I ended up running into some problems, especially with the this keyword."
How this works in arrow functions
In a regular function, this refers to the object when defined as a method of an object. We can therefor do:
const brunch = {
food: 'chicken-burger',
beverage: 'pine-apple juice',
order: function() {
return `I'll have the ${this.food} with ${this.beverage} please.`
}
}
console.log(brunch.order());
Calling brunch.order() will return "I'll have the chicken-burger with pine-apple juice please."
Let's edit that and use an arrow function for order
const brunch = {
food: 'chicken-burger',
beverage: 'pine-apple juice',
order: () => {
return `I'll have the ${this.food} with ${this.beverage} please.`
}
}
console.log(brunch.order());
This time, calling brunch.order() returns "I'll have the undefined with undefined please." Both this.food and this.beverage return undefined.
- It worked with the normal function, so what's going on? In the normal function,
this was our order object. When using an arrow function, this is not bound to anything and it just inherits from the parent scope which in this case is the window. Adding a console.log(this) before the return in the arrow function returns a Window object, so its looking for Window.food and Window.beverage which will obviously both be undefined.
"Arrow functions are therefore not suited as object methods."
" Another common problem area would be with event handlers. Here's an example:"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document object Model!</title>
<style>
.box {
background: #333;
}
</style>
</head>
<body>
<button id="click">Toggle</button>
<script>
const button = document.querySelector('#click');
button.addEventListener('click', function() {
console.log(this); // button
this.classList.toggle('box');
});
</script>
</body>
</html>
In the code above, this refers to the button. Clicking on the button toggles the colour as expected.
Change the function to an arrow function:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document object Model!</title>
<style>
.box {
background: #333;
}
</style>
</head><body>
<button id="click">Toggle</button>
<script>
const button = document.querySelector('#click');
button.addEventListener('click', () => {
console.log(this); // button
this.classList.toggle('box');
});
</script>
</body>
and this becomes the browser's window attribute. Clicking the button will give a TypeError error. If you rely on this in an event hanlder, a regular function may be necessary.
CALL APPLY BIND METHOD:
let name = {
firstname: 'dinesh',
lastname: 'silwal',
printFullName: function() {
console.log(this.firstname + " " +
this.lastname)
}
}
name.printFullName() // dinesh silwal
let name1 = {
firstname: 'Nabin',
lastname: 'shreastha'}
// using call() method
name.printFullName.call(name1); // Nabin shreastha
............................................................
"let say we need to use printFullName() method inside object
name1,
we can do this copying the printFullName() inside the object name1..
but that is not the best and intellectual way of doing that, it becomes
code repetition.."
"that's where call(),method comes into picture, using call
method we can do function or method borowing and use it with
data of some other object."
"take the object first which needs to be called, in ourcase
is name1.printFullName()"
"in callmethod 1st argument must be reference,
in simple term what we want "this keyword" be pointing to"
in our case refer to the object name1 and let see what
we got..
"test yourself" in your ide
NOTE: Explicit and Fixed Binding of “this” keyword
If we use call and apply method with calling function,
both of those methods take as their first parameter
as execution context.
"that is this binding."
- But the thing is we don't use method inside the object as follows and let use it outside the object.
let name = {
firstname: 'dinesh',
lastname: 'silwal',
}
let printFullName = function() {
console.log(this.firstname + " " + this.lastname)
}
printFullName.call(name) // dinesh silwal
let name1 = {
firstname: 'Nabin',
lastname: 'shreastha'
}
printFullName.call(name1) // Nabin shreastha
- let say we pass parameter inside the method printfulName(). Now the question is how we gone a add argument to it while using with call (). Let see in below eg :
- This is fine with one parameter but what if we have more one parameters. That where the concept of Apply(), method comes.
"Same concept applies for call() and apply() method, but the only difference is
the way we pass arguments"
let name = {
firstname: 'dinesh',
lastname: 'silwal',
}
// let pass paramter and look how do we call it
let printFullName = function(country) {
console.log(this.firstname + " " + this.lastname
+ " " + "from" + " " + country)
}
printFullName.call(name, 'Nepal') // dinesh silwal
let name1 = {
firstname: 'Nabin',
lastname: 'shreastha'
}
printFullName.call(name1, 'Nepal') // Nabin shreastha
If more than one arguments then what ??
- In case of call() method we pass it ,invidually but in case of apply(), method we pass it in Array list , that is only the basic difference between call() and apply().
let name = {
firstname: 'dinesh',
lastname: 'silwal',
}
let printFullName = function(country, city) {
console.log(this.firstname + " " + this.lastname + " " + "from"
+ " " + country + " " + "from" + " " + city)
}
printFullName.call(name, 'Nepal', 'kathmandu')
printFullName.apply(name, ['Nepal', 'kathmandu'])
// array list
let name1 = {
firstname: 'Nabin',
lastname: 'shreastha'
}
printFullName.call(name1, 'Nepal', 'kathmandu')
printFullName.apply(name1, ['Nepal', 'kathmandu'])//array list
Output:
dinesh silwal from Nepal from kathmandu
indexs.html:18 dinesh silwal from Nepal from kathmandu
indexs.html:18 Nabin shreastha from Nepal from kathmandu
indexs.html:18 Nabin shreastha from Nepal from kathmandu
Bind Method
- The only difference between bind() and call() , it gives you copy that
can be invoked later ??
DID YOU UNDERSTAND THAT ??
It looks exactly the same as call method but instead bind() method bind this
method printfulName() with a object name and name1 and returns copy of object
which can be invoked later.
let printFullName = function(country, city) {
console.log(this.firstname + " " + this.lastname + " " + "from" + " " + country + " " + "from" + " " + city)
}
let name1 = {
firstname: 'Nabin',
lastname: 'shreastha'
}
let printMyname = printFullName.bind(name1, 'Nepal',
'Kathmandu')
console.log(printMyname);
// output
ƒ (country, city) {
console.log(this.firstname + " " + this.lastname
+ " " + "from" + " " + country + " " + "from" + " " + city)
}
invoking later:
printMyname();
// output:
Nabin shreastha from Nepal from Kathmandu
Comments
Post a Comment