Anonymous Functions, this,
and Debugging
Lecture 9
Today’s Agenda
● Anonymous functions, callbacks, and this
● Debugging JS
Anonymous Functions, Callbacks, and
this
Arrow Functions: More Concise Anonymous
Functions
/* named function with one parameter that logs to the console. */
function sayHello(name) {
console.log("Hello " + name);
}
let sayHello = function(name) {
console.log("Hello " + name);
}
let sayHello = (name) => {
console.log("Hello " + name);
}
/* Equivalent function with no parens because there is only 1 parameter */
let sayHello = name => { console.log("Hello " + name); }
let sayHello = () => { console.log("Hello!"); };
An overview of when these are particularly useful in today’s reading. We’ll start to see more in JS
but you are not required to use them.
The Keyword this
All JavaScript code actually runs inside of "an object" that we can access with the keyword this
By default, code runs in the global window object (so this === window)
Event handlers attached in an event listener are bound to the element
Inside the handler, that element becomes this
function init() {
// this === window
id("btn1").addEventListener("click", namedFunction);
id("btn2").addEventListener("click", function() {
console.log("this === " + this); // this === #btn2
});
}
function namedFunction() {
console.log("this === " + this); // this === #btn1
}
Example
Anonymous Button: https://replit.com/@semihyumusak/AnonymousButton-21sp
Arrow Functions: More Concise Anonymous
Functions
function addSkittle() { ● Both 1. and 2. work equivalently -
// ... added to existing addSkittle code
2. uses an anonymous function!
// 1. with defined eatSkittle() function
skittle.addEventListener("dblclick", eatSkittle); ● Do not overuse these! Breaking
down our code into named
// same as 2., with anonymous function functions can be useful to reduce
skittle.addEventListener("dblclick", function() { redundancy and keep code
this.parentNode.removeChild(this);
});
understandable.
} ● If you have more than 3 lines of
code, it often should be a named
// Removes a skittle from the Jar when dblclicked function.
function eatSkittle() {
this.parentNode.removeChild(this); // or this.remove();
}
More JavaScript: What happens to this?
let defaultReply = "Hello World";
button.addEventListener("click", function() {
draftReply(defaultReply);
});
vs.
let defaultReply = "Hello World";
button.addEventListener("click", () => {
draftReply(defaultReply);
});
function draftReply(startingText) {
this.parentNode.appendNode( /*....*/ );
// ...
}
Parameter passing to Event Handlers
let defaultReply = "Hello World";
button.addEventListener("click", function() {
draftReply(defaultReply);
});
How else could we do this?
let defaultReply = "Hello World";
button.addEventListener("click", () => {
draftReply(defaultReply);
});
A Caveat: Arrow Functions do Not Bind this
We've seen how "this" refers to the bound element in an event handler. However, arrow
functions do not bind "this" the same way.
skittle.addEventListener("dblclick", function() {
// All good! this === div.skittle that was clicked
this.parentNode.removeChild(this);
id("result").textContent = ":O You ate a skittle...";
});
skittle.addEventListener("dblclick", () => {
// error! this === window
this.parentNode.removeChild(this);
id("result").textContent = ":O You ate a skittle...";
});
Comparing this with different callback functions
function init() {
id("btn1").addEventListener("click", namedFunction);
id("btn2").addEventListener("click", function() {
console.log("this === " + this); // this === #btn2
});
id("btn3").addEventListener("click", () => {
console.log("this === " + this); // this === window
});
}
function namedFunction() {
console.log("this === " + this); // this === #btn1
}
Debugging JS
Strategies
● Check if your JS file loaded
● console.log
● Read the error messages in the console
● Use the JS debugger in Chrome Dev Tools
Did Your JS File Load
● Example
● Use the "Network" tab in Chrome Dev Tools
● Did you spell your JS filename correctly?
● Are you listening for the "load" event
console.log Everything
After adding an event listener
myBtn.addEventListener("click", launchRocket);
function launchRocket() {
console.log('Launching!!!');
}
After accessing an element
let myBtn = qs('button');
console.log(myBtn);
After a complex calculation
const COLORS = ['red', 'blue', 'green'];
let randIndex = Math.floor(Math.random() * COLORS.length);
console.log(randIndex);
Read the Messages in the Console
Errors in your code are printed to the Chrome Dev Tools console
● Error message
● File the error originated from
● Line number
The console error messages even link you to the line in your code where the error
occurred!
Use the JS Debugger
Under the "Sources" tab in Chrome Dev Tools
● Set breakpoints to pause execution of your code at a desired point
● View variable values at that point
● Step in and out of functions
● ...and much, much more
Example
Skittles (Time Permitting)
More progress on Skittles