Chameleon and the Changing this in JavaScript
Thilak Ramanie
MSc Computing student @ DCU | Secure Software Engineering Major | Proficient in React.js, Angular, Node.js | Eagerly seeking full-time roles in Dublin, Ireland.
In JavaScript, the keyword this can be one of the trickiest concepts to grasp. Its behavior changes based on the context in which it is used, making it a powerful yet sometimes confusing feature. This guide will demystify this by explaining its behavior in various scenarios, using relatable analogies, and providing practical examples.
The Chameleon Analogy
A chameleon changes its color based on its surroundings. Similarly, the value of this in JavaScript changes depending on where and how it's used:
Examples:
function globalThis() {
console.log(this); // window (in browsers)
}
globalThis();
const obj = {
name: 'JavaScript',
showThis: function() {
console.log(this); // obj
}
};
obj.showThis();
function Person(name) {
this.name = name;
}
const person = new Person('John');
console.log(person.name); // John
document.getElementById('myButton').addEventListener('click', function() {
console.log(this); // The button element
});
Explicit Binding:
Javascript provides methods like call, apply, and bind to set the value of this explicitly.
领英推荐
function showName() {
console.log(this.name);
}
const obj1 = { name: 'Alice' };
const obj2 = { name: 'Bob' };
showName.call(obj1); // Alice
showName.apply(obj2); // Bob
const boundFunction = showName.bind(obj1);
boundFunction(); // Alice
Arrow Functions and Lexical Scoping:
Arrow functions do not bind their own this; instead, they inherit it from the parent scope, a concept known as "lexical scoping." This makes arrow functions a great choice in some scenarios but problematic in others.
const myFunction = () => {
console.log(this);
};
myFunction(); // window
const myObject = {
myMethod: () => {
console.log(this);
}
};
myObject.myMethod(); // window
In this scenario, this is still the global object. Even though myMethod is called on myObject, the arrow function does not bind this to myObject.
const myMethod = myObject.myMethod;
myMethod(); // window
Again, this is the global object because the arrow function inherits this from the global scope.
Correct Usage of Arrow Functions in Methods:
const myObject = {
myArrowFunction: null,
myMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myArrowFunction(); // this === myObject
const myArrowFunction = myObject.myArrowFunction;
myArrowFunction(); // this === myObject
In this example, when myObject.myMethod() is called, it initializes myObject.myArrowFunction with an arrow function. This arrow function inherits this from myMethod, making it refer to myObject.
Conclusion:
So, understanding this in JavaScript is all about knowing the context, just like knowing, when a chameleon will change color. Remember, this can be tricky, but we can get the hang of it with practice. As they say,
A chameleon is only as good as its camouflage, and a JavaScript developer is only as good as their grasp of "this."