Share
Explore

Understanding the this Keyword in JavaScript


Introduction

In JavaScript, the this keyword is a fundamental concept that can be confusing to first-term students.
It refers to the context in which the current code is executing, and its value can change based on how and where a function is called.
Understanding this is crucial for effectively managing and manipulating both the HTML Document Object Model (DOM) and the JavaScript Browser Object Model (BOM).

What is this?

In JavaScript, this refers to the object that the function is a method of. The value of this is determined at runtime, depending on the execution context:
Global context: In the global execution context (outside of any function), this refers to the global object whether in strict mode or not.
Function context: Inside a function, the value of this depends on how the function was called. If it was called as a method of an object, this is set to the object the method is called on.

Examples Demonstrating this in Different Contexts

1. Global Context

javascript
Copy code
console.log(this.document === document); // true
console.log(this); // Logs global object (window in browser)

Here, this refers to the global window object, under which all global variables and browser-specific objects reside.

2. Function Context

javascript
Copy code
function show() {
console.log(this);
}
show(); // In a browser, this will log the Window object.

In non-strict mode, a regular function call like this has this pointing to the global object (window). In strict mode, this would be undefined.

3. Object Method

javascript
Copy code
const person = {
firstName: "James",
lastName: "T. Kirk",
fullName: function() {
return `${this.firstName} ${this.lastName}`;
}
};
console.log(person.fullName()); // James T. Kirk

In the method call of an object, this refers to the object the method is called on.

How Arrow Functions Affect this

Arrow functions do not have their own this context; instead, they inherit this from the surrounding code where they are defined, which is known as lexical scoping.

Example with DOM

javascript
Copy code
document.getElementById('btn').addEventListener('click', () => {
console.log(this); // Logs the window object, not the button
});

Here, the arrow function inherits this from its surrounding scope, which is the global window object in a browser, unlike a regular function which would have this set to the element that triggered the event (e.g., the button).

Example with BOM

javascript
Copy code
setTimeout(() => {
console.log(this); // Still window object
}, 1000);

Even inside a setTimeout (which is part of BOM), the arrow function keeps this from its lexical context, unlike a regular function which would have this set to the global object (or undefined in strict mode).

Conclusion

Understanding how this works in different contexts is crucial for programming effectively in JavaScript, especially when manipulating the DOM and handling events in the BOM. By using arrow functions, you can avoid common pitfalls related to this, making your code cleaner and more intuitive. Now, let's practice what we've learned with some exercises that reinforce these concepts.

Let's practice what we've learned with some exercises that reinforce these concepts => present 10 drills with HTML DOM and JavaScript BOM

Practical Drills: Reinforcing the Concepts of this and Arrow Functions in DOM and BOM

These exercises are designed to help first-term students deepen their understanding of the this keyword in various contexts, specifically in interactions with the HTML DOM and JavaScript BOM. The exercises will also incorporate the use of arrow functions to highlight their behavior in these contexts.

Drill 1: DOM Button Click

Objective: Understand how this behaves in event handlers.
Task:
Create an HTML button with the text "Click Me".
Attach an event listener using a regular function and log this.
Repeat with an arrow function and compare the outputs.
html
Copy code
<button id="clickMe">Click Me</button>
<script>
document.getElementById('clickMe').addEventListener('click', function() {
console.log(this); // Button object
});
document.getElementById('clickMe').addEventListener('click', () => {
console.log(this); // Window object
});
</script>

Drill 2: Modifying Element Styles

Objective: Manipulate CSS styles using this.
Task:
Create a list of items.
Set up an event where clicking an item changes its color using this.
html
Copy code
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script>
document.querySelectorAll('li').forEach(item => {
item.addEventListener('click', function() {
this.style.color = 'red';
});
});
</script>

Drill 3: Using setTimeout in Methods

Objective: Observe how this behaves in BOM methods.
Task:
Define an object with a method that sets its property after a delay.
Use both traditional and arrow functions to see the difference.
javascript
Copy code
const timerObj = {
message: 'Hello',
startTimer: function() {
setTimeout(function() {
console.log(this.message); // undefined
}, 1000);
setTimeout(() => {
console.log(this.message); // Hello
}, 1000);
}
};
timerObj.startTimer();

Drill 4: Event Delegation

Objective: Apply event delegation with this.
Task:
Create a container with multiple buttons.
Use event delegation on the container to log the text of the button clicked.
html
Copy code
<div id="buttonContainer">
<button>One</button>
<button>Two</button>
<button>Three</button>
</div>
<script>
document.getElementById('buttonContainer').addEventListener('click', function(e) {
if(e.target.tagName === 'BUTTON') {
console.log(this); // Container div
console.log(e.target.innerHTML); // Button text
}
});
</script>

Drill 5: Manipulating Classes

Objective: Toggle classes using this in an event.
Task:
Create several div elements.
Set up an event to toggle a class active on click using this.
html
Copy code
<div>Click to toggle</div>
<div>Click to toggle</div>
<div>Click to toggle</div>
<script>
document.querySelectorAll('div').forEach(div => {
div.addEventListener('click', function() {
this.classList.toggle('active');
});
});
</script>

Drill 6: Dynamic Element Creation

Objective: Use this to handle dynamically created elements.
Task:
Create a button that when clicked, creates a new button.
New buttons, when clicked, should log a message using this.
html
Copy code
<button id="createButton">Create Button</button>
<script>
document.getElementById('createButton').addEventListener('click', function() {
const newButton = document.createElement('button');
newButton.textContent = 'New Button';
newButton.addEventListener('click', function() {
console.log(this.textContent); // Logs 'New Button'
});
document.body.appendChild(newButton);
});
</script>

Drill 7: Integrating Arrow Functions in Callbacks

Objective: Use arrow functions in API callbacks to preserve this.
Task:
Define an object that fetches data and logs it using this.
Use an arrow function in the fetch callback.
javascript
Copy code
const apiCaller = {
dataUrl: 'https://api.example.com/data',
fetchData: function() {
fetch(this.dataUrl).then(response => response.json()).then(data => {
console.log(this); // apiCaller object
console.log(data);
});
}
};
apiCaller.fetchData();

Drill 8: Handling Mouse Over Events

Objective: Understand event handling and this with mouse events.
Task:
Create several images.
Add a mouseover event to change the image opacity using this.
html
Copy code
<img src="image1.jpg">
<img src="image2.jpg">
<script>
document.querySelectorAll('img').forEach(img => {
img.addEventListener('mouseover', function() {
this.style.opacity = 0.5;
});
});
</script>

Drill 9: Form Input Validation

Objective: Validate form input using this.
Task:
Create a form with an input field for email.
Add a blur event to validate the email using this.
html
Copy code
<form>
<input type="email" id="emailInput" placeholder="Enter your email">
</form>
<script>
document.getElementById('emailInput').addEventListener('blur', function() {
if(this.value.includes('@')) {
this.style.borderColor = 'green';
} else {
this.style.borderColor = 'red';
}
});
</script>

Drill 10: Scrolling Events

Objective: Utilize this with scrolling events to manipulate elements based on scroll position.
Task:
Create a header element.
Change the header's background color based on the scroll position using this.
html
Copy code
<header id="mainHeader">Scroll Down</header>
<script>
window.addEventListener('scroll', function() {
const header = document.getElementById('mainHeader');
header.style.backgroundColor = window.scrollY > 100 ? 'blue' : 'transparent';
});
</script>

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.