Skip to content

Commit 3f3312b

Browse files
committed
this keyword with arrow function
1 parent 4838cd0 commit 3f3312b

7 files changed

+192
-64
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Unlike regular functions, arrow functions do not have their own **this**.
2+
3+
```js
4+
let user = {
5+
name: "GFG",
6+
gfg1: () => {
7+
console.log("hello " + **this**.name) // no '**this**' binding here
8+
},
9+
gfg2() {
10+
console.log("Welcome to " + **this**.name) // '**this**' binding works here
11+
},
12+
}
13+
user.gfg1() // => undefined
14+
user.gfg2() // 'Welcome to GFG'
15+
```
16+
17+
You cannot rebind **this**. in an arrow function. It will always be defined as the context in which it was defined. If you require \***\*this\*\*** to be meaningful you should use a normal function.
18+
19+
From the ECMAScript 2015 Spec:
20+
21+
Any reference to arguments, super, **this**, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically **this** will be the Function Environment of an immediately enclosing function.
22+
23+
**this** inside an arrow function always 'inherits' the **this** from the enclosing scope. That is a feature of arrow functions. But you can still bind all other parameters of an arrow function. Just not **this**
24+
25+
You cannot bind a value since the **this** is already binded.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
### Arguments objects are not available in arrow functions, but are available in regular functions.
2+
3+
```js
4+
let user = {
5+
show() {
6+
console.log(arguments)
7+
},
8+
}
9+
user.show(1, 2, 3) // => [Arguments] { '0': 1, '1': 2, '2': 3 }
10+
```
11+
12+
But the below will print some strange output
13+
14+
```js
15+
let user = {
16+
show_ar: () => {
17+
console.log(...arguments)
18+
},
19+
}
20+
21+
user.show_ar(1, 2, 3)
22+
```
23+
24+
### Can NOT Use new keyword with arrow function
25+
26+
Regular functions created using function declarations or expressions are ‘constructible’ and ‘callable’. Since regular functions are constructible, they can be called using the ‘new’ keyword. However, the arrow functions are only ‘callable’ and not constructible. Thus, we will get a run-time error on trying to construct a non-constructible arrow functions using the new keyword.
27+
28+
```js
29+
let x = function() {
30+
console.log(arguments)
31+
}
32+
new x(1, 2, 3) // => [Arguments] { '0': 1, '1': 2, '2': 3 }
33+
// The above will compile properly
34+
35+
let x = () => {
36+
console.log(arguments)
37+
}
38+
new x(1, 2, 3) // => TypeError: x is not a constructor
39+
```
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,53 @@
1-
# Arrow functions are cool in ES6. When should you NOT use arrow functions. Name three or more cases.
1+
### Arrow functions are cool in ES6. When should you NOT use arrow functions. Name three or more cases.
22

3-
Arrow functions are neat but are not suitable for all use cases. For those who are ready to get rid of `function` and move on to arrow functions, it's time to examine a simple scenario where the arrow function would complicate your logic.
4-
5-
## 1. Event Handlers
3+
### 1. Event Handlers
64

75
Let's look at this example, we have a link on our page with an id of `myLink`. Every time you hover over this link, a CSS class `highlight` is toggled and the text is highlighted.
86

97
```js
10-
var myLink = document.getElementById('myLink');
11-
myLink.addEventListener('mouseenter', function(){
12-
this.classList.toggle('highlight');
13-
console.log(this.classList);
14-
});
8+
var myLink = document.getElementById("myLink")
9+
myLink.addEventListener("mouseenter", function() {
10+
this.classList.toggle("highlight")
11+
console.log(this.classList)
12+
})
1513
```
14+
1615
This logs `highlight`.
1716

1817
Using ES6 syntax, this works as expected. Now let's try that in ES6 using arrow functions:
1918

2019
```js
21-
const myLink = document.getElementById('myLink');
22-
myLink.addEventListener('mouseenter', () => {
23-
this.classList.toggle('hightlight');
24-
console.log(this.classList);
25-
});
20+
const myLink = document.getElementById("myLink")
21+
myLink.addEventListener("mouseenter", () => {
22+
this.classList.toggle("hightlight")
23+
console.log(this.classList)
24+
})
2625
```
27-
This logs `TypeError: Cannot read property 'classList' of undefined`.
28-
29-
If you use an arrow function, the keyword ``this`` is not bound to that element. If we use a regular function, the keyword this will be bound to the element we clicked!
30-
31-
32-
33-
If you're not sure whether an arrow function is appropriate, [Kyle Simpson](https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch2.md) provides us with this awesome chart:
3426

35-
![Arrow Functions Visual Aid](https://github.com/getify/You-Dont-Know-JS/raw/master/es6%20%26%20beyond/fig1.png)
27+
This logs `TypeError: Cannot read property 'classList' of undefined`.
3628

29+
When using an arrow function `this` is not bound to anything and it just inherits it from the parent scope which may be window. If we use a regular function, the keyword 'this' will be bound to the element we clicked. Remember,
3730

3831
## 2: Object Methods
3932

4033
```js
4134
const person = {
42-
points: 23,
43-
score: () => {
44-
return this.points++;
45-
}
35+
points: 23,
36+
score: () => {
37+
return this.points++
38+
},
4639
}
4740

48-
person.score();
41+
person.score()
4942

50-
console.log(person.points) // it ouputs 23 irrepective of howmany times i run the above block of code
43+
console.log(person.points) // it outputs 23 irrespective of how many times i run the above block of code instead of getting incremented by earlier call of person.score().
5144
```
45+
5246
We have our method called score, and whenever we call person.score, it should add one to our points, which is currently 23.
5347

5448
If we run person.score(); a few times, we should be at 26 or something.
5549

56-
But if I call person, points is still at 23. Why?
50+
But if I call person.points is still at 23. Why?
5751

5852
Because it’s trying to add points to the window! Remember, when using an arrow function this is not bound to anything and it just inherits it from the parent scope which in this case is the window.
5953

@@ -71,4 +65,5 @@ person.score();
7165

7266
console.log(person.points)
7367
```
74-
And now, first output is 24 and then 25 and so on..
68+
69+
And now, first output is 24 and then 25 and so on..
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[From w3school](https://www.w3schools.com/js/js_function_call.asp)
2+
3+
In JavaScript all functions are object methods.
4+
5+
If a function is not a method of a JavaScript object, it is a function of the global object (see previous chapter).
6+
7+
```js
8+
var person = {
9+
firstName: "John",
10+
lastName: "Doe",
11+
fullName: function() {
12+
return this.firstName + " " + this.lastName
13+
},
14+
}
15+
person.fullName()
16+
```
17+
18+
In a function definition, this refers to the "owner" of the function.
19+
20+
In the example above, this is the person object that "owns" the fullName function.
21+
22+
In other words, this.firstName means the firstName property of this object.
23+
24+
The call() method can be used to invoke (call) a method with an owner object as an argument (parameter).
25+
26+
With call(), an object can use a method belonging to another object.
27+
28+
```js
29+
var person = {
30+
fullName: function() {
31+
return this.firstName + " " + this.lastName
32+
},
33+
}
34+
var person1 = {
35+
firstName: "John",
36+
lastName: "Doe",
37+
}
38+
var person2 = {
39+
firstName: "Mary",
40+
lastName: "Doe",
41+
}
42+
person.fullName.call(person1) // Will return "John Doe"
43+
```

Javascript/call-apply-bind/call-function.md renamed to Javascript/call-apply-bind/call-function-basics-2.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,31 @@ f() // => 10
2626
f.call(o) // => 15
2727
```
2828

29+
### Very Importantly note, the call() method as above will NOT work in arrow function. And this.x will produce undefined. Because, Unlike regular functions, arrow functions do not have their own 'this'
30+
31+
```js
32+
global.x = 10
33+
34+
const obj = {
35+
x: 15,
36+
func: () => console.log(this.x),
37+
func2: function() {
38+
console.log(this.x)
39+
},
40+
}
41+
42+
const func = () => console.log(this.x)
43+
44+
func() // => undefined
45+
func.call(obj) // => undefined
46+
obj.func.call(obj) // => undefined
47+
// But the following will work as expected
48+
obj.func2.call(obj) // => 15, accessing the
49+
```
50+
2951
The first invocation of f() will display the value of 10, because this references the global object. The second invocation (via the call method) however, will display the value 15. 15 is the value of the x property inside object o.
3052

31-
### The call() method invokes the function and uses its first parameter as the this pointer inside the body of the function. In other words - we've told the runtime what object to reference as this while executing inside of function f().
53+
### The call() method invokes the function and uses its first parameter as the this pointer inside the body of the function. In other words - we've told the runtime what object to reference as 'this' while executing inside of function f().
3254

3355
### The apply() method is identical to call(), except apply() requires an array as the second parameter. The array represents the arguments for the target method.
3456

Javascript/curried-function.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#### Is a technique for converting function calls with N arguments into chains of N function calls with a single argument for each function call?
2+
3+
#### Currying always returns another function with only one argument until all of the arguments have been applied. So, we just keep calling the returned function until we’ve exhausted all the arguments and the final value gets returned.
4+
15
Example
26

37
```js

Javascript/js-basics/this-keyword.js

+33-33
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,68 @@
33
44
Inside a function, the value of this depends on how the function is called.
55
6-
Case-1 - WITHOUT STRICT MODE - Since the following code is not in strict mode, and because the value of this is not set by the call, this will default to the global object, which is window in a browser.
6+
Case-1 - WITHOUT STRICT MODE - If a function is not in strict mode, and if the value of this is not set by the call, this will default to the global object, which is window in a browser.
77
8-
Case-2 - In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, so, in the following case, this will default to undefined. So, in strict mode, if this was not defined by the execution context, it remains undefined.
8+
Case-2 - In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, 'this' will default to undefined. So, in strict mode, if this was not defined by the execution context, it remains undefined.
99
1010
*/
1111

1212
// Case-1 - WITHOUT STRICT MODE - Since the following code is not in strict mode, and because the value of this is not set by the call, this will default to the global object, which is window in a browser.
1313

1414
function f1() {
15-
return this;
15+
return this
1616
}
1717

1818
// In a browser:
19-
f1() === window; // true
19+
f1() === window // true
2020

2121
// In Node:
22-
f1() === global; // true
22+
f1() === global // true
2323

2424
// Case-2 - In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, so, in the following case, this will default to undefined. So, in strict mode, if this was not defined by the execution context, it remains undefined.
2525

2626
function f2() {
27-
"use strict"; // see strict mode
28-
return this;
27+
"use strict"
28+
return this
2929
}
3030

31-
f2() === undefined; // true
31+
f2() === undefined // true
3232

3333
// In the Case-2 above, `this` was returned to be undefined, because f2 was called directly and not as a method or property of an object (e.g. window.f2()).
3434

3535
// To pass the value of this from one context to another, use call(), or apply():
3636

3737
// An object can be passed as the first argument to call or apply and this will be bound to it.
38-
var obj = { a: "Custom" };
38+
var obj = { a: "Custom" }
3939

4040
// This property is set on the global object
41-
var a = "Global";
41+
var a = "Global"
4242

4343
function whatsThis() {
44-
return this.a; // The value of this is dependent on how the function is called
44+
return this.a // The value of this is dependent on how the function is called
4545
}
4646

47-
whatsThis(); // 'Global'
48-
whatsThis.call(obj); // 'Custom'
49-
whatsThis.apply(obj); // 'Custom'
47+
whatsThis() // 'Global'
48+
whatsThis.call(obj) // 'Custom'
49+
whatsThis.apply(obj) // 'Custom'
5050

5151
/* Where a function uses the 'this' keyword in its body, its value can be bound to a particular object in the call using the call() or apply() methods which all functions inherit from Function.prototype. */
5252

5353
function add(c, d) {
54-
return this.a + this.b + c + d;
54+
return this.a + this.b + c + d
5555
}
5656

57-
var o = { a: 1, b: 3 };
57+
var o = { a: 1, b: 3 }
5858

5959
// The first parameter is the object to use as
6060
// 'this', subsequent parameters are passed as
6161
// arguments in the function call
62-
add.call(o, 5, 7); // 16
62+
add.call(o, 5, 7) // 16
6363

6464
// The first parameter is the object to use as
6565
// 'this', the second is an array whose
6666
// members are used as the arguments in the function call
67-
add.apply(o, [10, 20]); // 34
67+
add.apply(o, [10, 20]) // 34
6868

6969
// *********************** EXPLANATION - 2 **************************************//
7070
/* MORE TEST CASE - Case-1
@@ -76,23 +76,23 @@ B) By default the execution context for an execution is global which means that
7676
“window” object is the global object in case of browser and in Node.JS environment, a special object “global” will be the value of “this”.
7777
*/
7878

79-
global.a = 2;
79+
global.a = 2
8080

8181
function foo() {
82-
return this.a;
82+
return this.a
8383
}
8484

85-
console.log(foo()); // => 2
85+
console.log(foo()) // => 2
8686

8787
// SECOND TEST CASE
8888

89-
var b = 2;
89+
var b = 2
9090

9191
function foo1() {
92-
console.log(this.b);
92+
console.log(this.b)
9393
}
9494

95-
foo1(); // => 'undefined'
95+
foo1() // => 'undefined'
9696

9797
// Explanation of the above - I got 'undefined' because in VS-Code here, I am in node environment so just declaring var b = 2 will not attach the variable to the 'global' environment of vs-code
9898

@@ -101,24 +101,24 @@ When an Object’s method is invoked then “this” refers to the object which
101101

102102
var obj = {
103103
c: 3,
104-
foo3: foo3
105-
};
104+
foo3: foo3,
105+
}
106106

107107
function foo3() {
108-
console.log(this.c);
108+
console.log(this.c)
109109
}
110-
obj.foo3(); // => 3
110+
obj.foo3() // => 3
111111

112112
// FOURTH TEST CASE
113113
function foo4() {
114-
console.log(this === global);
114+
console.log(this === global)
115115
}
116-
foo4(); // => true
116+
foo4() // => true
117117

118118
// FIFTH TEST CASE - If strict mode is enabled for any function then the value of “this” will be “undefined” as in strict mode, global object refers to undefined in place of windows object.
119119

120120
function foo5() {
121-
"use strict";
122-
console.log(this === global);
121+
"use strict"
122+
console.log(this === global)
123123
}
124-
foo5(); // => false
124+
foo5() // => false

0 commit comments

Comments
 (0)