- What is variable hoisting?
- What are the rules of lexical scoping?
- What is the value of
this
in an event handler?
- Scope: Either the global scope or the current function
- Context: Whatever
this
is equal to when you console.log it
// What will this snippet of code output?
var tiredSoul = "Adam Ewing";
var futureSelf = "Zachry";
function logMe () {
var tiredSoul = "Luisa Rey";
var sensedConnection = "Robert Frobisher";
console.log(tiredSoul, sensedConnection, futureSelf);
}
logMe()
// What will this snippet of code output?
for(var i = 0; i < 10; i++) {
console.log(i);
document.addEventListener('DOMContentLoaded', function() {
console.log(i);
});
}
// What does this output?
var x = 2
function hoister () {
console.log(x)
x = 3
}
hoister()
// What does this output?
var x = 2
function hoister () {
console.log(x)
var x = 3
}
hoister()
// What does this output?
var a = 2
console.log(this.a) // it matters...
- Browser: global
window
object - Node Console:
global
object - Node Script: empty object
{}
- Never rely on default contexts: Bad Pratice
// What does this output in the browser? In the Node console? In a Node script?
var a = 2
function context() {
var a = 3
console.log(this.a)
}
context()
var obj = {
a: 2,
b: function () {
console.log(this.a)
}
}
obj.b() // What's the output?
// What's the output when you click on a page?
document.addEventListener('click', function () {
console.log(this)
})
var obj = {
a: 2,
b: function () {
console.log(this.a)
}
}
// What's the output on a click?
document.addEventListener('click', obj.b)
- 3 Javascript functions for modifying context
- .bind(context)
- .apply(context, [function_args])
- .call(context, function_arg1, function_arg2)
Creates a copy of a function with a modified context
function sameSoul(soulC, soulD){
return this.soulA + " is " + this.soulB + " is " + soulC + " is " + soulD + "!";
}
var noGood = {
soulA: "Colonel Mustard",
soulB: "Henry Goose",
}
var badSouls = sameSoul.bind(noGood);
badSouls("Professor Plum", "Mrs. Peacock"); // "Colonel Mustard is Henry Goose is Professor Plum is Mrs. Peacock!"
// Modify this code so that it prints 2 on a click event
var obj = {
a: 2,
b: function () {
console.log(this.a)
}
}
document.addEventListener('click', obj.b)
- Same functionality, different syntax
- Executes a function with a specified context
myFunction.call(context, arg1, arg2)
myFunction.apply(context, [arg1, arg2])
var obj = {
a: 2
}
function badAddition (b) {
return this.a + b
}
badAddition(3) // NaN
badAddition.call(obj, 3) // 5
function sameSoul(soulC, soulD){
return this.soulA + " is " + this.soulB + " is " + soulC + " is " + soulD + "!";
}
var noGood = {
soulA: "Colonel Mustard",
soulB: "Henry Goose",
}
sameSoul.apply(noGood, ["Professor Plum", "Mrs. Peacock"]); // "Colonel Mustard is Henry Goose is Professor Plum is Mrs. Peacock!"
function log () {
console.log(this.firstChild)
}
document.addEventListener('click', function () {
log() // modify this line with .call so that it prints the document's first child element
})
// Modify this to print Keyan instead of Grant
// 1) Modify it using .bind
// 2) Modify it using .apply
this.wanderinSoul = "Grant";
var lemniscate = {
wanderinSoul: "Keyan",
getWanderer: function() { return this.wanderinSoul; }
};
var endingSoul = lemniscate.getWanderer;
endingSoul();
- Scopes are well defined. Use them wisely.
- Conflicting variable names across different scopes cause weird errors. Avoid them
- Context is a difficult beast. Avoid it unless necessary. Explicit over implicit