Why the "this" Keyword Behaves Differently in Regular Functions and Arrow Functions
Hargun Singh
Posted on July 27, 2024
The this
keyword in JavaScript can be confusing because it behaves differently in regular functions and arrow functions. In this blog post, we will explain how this
works in both types of functions, explore why these differences exist, and provide the basic knowledge you need to understand this
in JavaScript.
Regular Functions
Regular functions in JavaScript are defined using the function
keyword. The value of this
in these functions depends on how the function is called. Here are several examples:
1. Global Context
- Non-Strict Mode:
function regularFunction() {
console.log(this);
}
regularFunction(); // Logs the global object (window in browsers)
-
Explanation: In non-strict mode, when a function is called in the global context (not as a method of an object),
this
refers to the global object (window
in browsers orglobal
in Node.js).- Strict Mode:
'use strict';
function regularFunction() {
console.log(this);
}
regularFunction(); // Logs undefined
-
Explanation: In strict mode,
this
remainsundefined
when a function is called in the global context, providing a safer environment by preventing accidental modifications to the global object.
2. Method Call
When a function is called as a method of an object, this
refers to that object.
- Example:
const obj = {
method: function() {
console.log(this);
}
};
obj.method(); // Logs obj
-
Explanation: In this case,
this
points toobj
because the function is called as a method ofobj
.- Strict Mode: The behavior remains the same in strict mode.
3. Constructor Call
When a function is used as a constructor (called with the new
keyword), this
refers to the newly created instance.
- Example:
function Person(name) {
this.name = name;
this.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
}
const person1 = new Person('Alice');
person1.sayHello(); // Logs "Hello, my name is Alice"
const person2 = new Person('Bob');
person2.sayHello(); // Logs "Hello, my name is Bob"
-
Explanation: When called with
new
,this
inside thePerson
constructor function refers to the new instance being created. Each new instance (person1
andperson2
) gets its ownname
property andsayHello
method.- Strict Mode: The behavior remains the same in strict mode.
4. Explicit Binding
You can explicitly bind this
using call
, apply
, or bind
.
- Example:
function regularFunction() {
console.log(this);
}
const obj = { value: 42 };
regularFunction.call(obj); // Logs obj
regularFunction.apply(obj); // Logs obj
const boundFunction = regularFunction.bind(obj);
boundFunction(); // Logs obj
-
Explanation:
call
andapply
immediately invoke the function withthis
set toobj
, whilebind
creates a new function withthis
permanently bound toobj
.- Strict Mode: The behavior remains the same in strict mode.
Arrow Functions
Arrow functions, introduced in ES6, do not have their own this
context. Instead, they inherit this
from the surrounding (lexical) scope. This makes arrow functions useful in certain situations.
1. Lexical this
Arrow functions inherit this
from the scope in which they are defined.
- Non-Strict Mode:
const arrowFunction = () => {
console.log(this);
};
arrowFunction(); // Logs the global object (window in browsers)
-
Explanation: Arrow functions do not have their own
this
; they usethis
from the surrounding scope. Here, it refers to the global object because the function is defined in the global scope.- Strict Mode:
'use strict';
const arrowFunction = () => {
console.log(this);
};
arrowFunction(); // Logs undefined
-
Explanation: In strict mode, if the surrounding scope is global,
this
remainsundefined
as inherited from the surrounding scope.
2. Method Call
Unlike regular functions, arrow functions do not get their own this
when called as methods. They inherit this
from the enclosing scope.
- Example:
const obj = {
method: () => {
console.log(this);
}
};
obj.method(); // Logs the global object (window in browsers) or undefined in strict mode
-
Explanation: Arrow functions do not bind their own
this
but inherit it from the lexical scope. In this example,this
refers to the global object orundefined
in strict mode, notobj
.-
Strict Mode: Logs
undefined
, notobj
.
-
Strict Mode: Logs
3. Arrow Function Inside Another Function
When an arrow function is defined inside another function, it inherits this
from the outer function.
- Example:
function outerFunction() {
const arrowFunction = () => {
console.log(this);
};
arrowFunction();
}
const obj = { value: 42, outerFunction: outerFunction };
obj.outerFunction(); // Logs obj, because `this` in arrowFunction is inherited from outerFunction
-
Explanation: In this case,
this
inside the arrow function refers to the samethis
as inouterFunction
, which isobj
.- Strict Mode: The behavior remains the same in strict mode.
4. Arrow Function in Event Handlers
Arrow functions in event handlers inherit this
from the surrounding lexical scope, not from the element that triggers the event.
- Example:
const button = document.querySelector('button');
button.addEventListener('click', () => {
console.log(this);
}); // Logs the global object (window in browsers) or undefined in strict mode
-
Explanation: The arrow function does not bind
this
to the button element; it inherits it from the surrounding scope, which is the global scope orundefined
in strict mode.-
Strict Mode: Logs
undefined
, not the button element.
-
Strict Mode: Logs
Why These Differences?
The difference between regular functions and arrow functions lies in how they handle this
:
-
Regular Functions: The value of
this
is dynamic and determined by the call-site (how the function is called). -
Arrow Functions: The value of
this
is lexical and set at the time the function is defined, based on thethis
value of the enclosing execution context.
Key Concepts to Understand
To understand the behavior of this
in JavaScript, you need to know the following concepts:
-
Execution Context: The context in which code is executed, affecting how
this
is determined. -
Call-site: The location in code where a function is called, influencing the value of
this
in regular functions. -
Lexical Scoping: How
this
is inherited in arrow functions from the surrounding scope. -
Strict Mode: How strict mode changes the default behavior of
this
in certain contexts.
Summary
-
Regular Functions:
this
is dynamic and determined by the call-site. -
Arrow Functions:
this
is lexical and determined by the surrounding scope when the function is defined.
Understanding these distinctions will help you write more predictable and maintainable JavaScript code. Whether you're using regular functions or arrow functions, knowing how this
works is crucial for effective JavaScript development.
Your Turn!
I’d love to hear your thoughts and experiences with the this keyword. Have you encountered any tricky situations where the behavior of this caused unexpected results?
Feel free to leave your questions or comments below. Engaging with the content and asking questions is a great way to deepen your understanding and foster a community discussion. Your feedback will help me create more insightful and useful content in the future!
Posted on July 27, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
September 2, 2024
September 19, 2024
August 20, 2024