this, call, apply, bind
Managing Execution Context in JS
Objectives
- Define "Execution Context"
- Describe how is defined
- Use Call, Apply and Bind to set the execution context
this
Execution Context
n. The circumstances in which an event occurs; a setting.
Context
Execution
v. To perform; do.
Execution Context
Execution Context
The object a function lives inside of -- the environment in which a function executes
var math = {
addTwo : function (num1, num2) {
console.log(arguments);
console.log(this);
return num1 + num2;
},
x: 7
}
math.addTwo(1,2)
Execution Context
Execution Context
The object a function lives inside of -- the environment in which a function executes
var math = {
addTwo : function (num1, num2) {
console.log(arguments);
console.log(this);
return num1 + num2;
},
x: 7
}
math.addTwo(1,2)
Execution Context: this
Execution Context
The object a function lives inside of -- the environment in which a function executes
var math = {
addTwo : function (num1, num2) {
console.log(arguments);
console.log(this);
return num1 + num2;
},
x: 7
}
math.addTwo(1,2)
this encloses the *entire* object's scope!
Execution Context: Arguments
The object a function lives inside of -- the environment in which a function executes
var math = {
addTwo : function (num1, num2) {
console.log(arguments);
console.log(this);
return num1 + num2;
},
x: 7
}
math.addTwo(1,2)
arguments is an array-like list of arguments in the function
What will happen?
- A: 7,
- B: undefined,
- C: error
- D: other behavior
var math = {
addTwo : function (num1, num2) {
console.log(arguments, "arguments");
console.log(this, "this");
console.log(x); // what will this line do?
return num1 + num2;
},
x: 7
}
math.addTwo(1,2)
Think, Pair, Share!
x isn't defined in scope!
var math = {
addTwo : function (num1, num2) {
console.log(arguments, "arguments");
console.log(this, "this");
console.log(x); // what will this line do?
return num1 + num2;
},
x: 7
}
math.addTwo(1,2)
how do we print the value of x?
var math = {
addTwo : function (num1, num2) {
console.log(arguments, "arguments");
console.log(this, "this");
console.log(x); // what will this line do?
return num1 + num2;
},
x: 7
}
math.addTwo(1,2)
how do we print the value of x?
Summary:
arguments
this
An array-like object that contains the parameters passed into the function in order.
The calling context of the function- the object the function exists inside of.
Using call: setting "this"
function defaultContext () {
console.log(this);
}
defaultContext()
Show of hands, what is this?
Using call: setting "this"
function defaultContext () {
console.log(this);
}
var cat = {
name: "Felix",
furColor: "black"
}
defaultContext.call(cat);
This function's calling context is the global object
We can set the context explicitly
Call
function aGloballyScopedFunction () {
console.log("THIS IS: ", this)
}
aGloballyScopedFunction()
aGloballyScopedFunction.call(cat)
this
window || global
cat
this
arguments
function addMany() {
var total = 0;
for (var i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
addMany(50,50,300,200);
It's like a limited edition array!
(it's super limited)
What does that mean?
function addMany() {
this.total = 0;
for (var i = 0; i < arguments.length; i++) {
this.total += arguments[i];
}
return this.total;
}
someObject = {}
someNumbers = [50,50,300,200]
addMany.apply(someObject,someNumbers);
Apply: an Example
someNumbers Array is passed into addMany as multiple arguments
function addMany() {
this.total = 0;
for (var i = 0; i < arguments.length; i++) {
this.total += arguments[i];
}
return this.total;
}
someObject = {}
someNumbers = [50,50,300,200]
addMany.call(someObject,someNumbers);
Call: Same Params!
Call & Apply: contrast
Call: comma separated
Apply: takes an array
SPOT CHECK!
What takes in what??
Bind & Apply
function doNotArgue(a,b,c,d) {
console.log(arguments)
arguments.pop()
}
doNotArgue("you","can't","stop","me")
Arguments is not an array
function doNotArgue(a,b,c,d) {
console.log(arguments)
let itBe = Array.prototype.slice.call(arguments)
itBe.pop()
console.log(itBe)
}
doNotArgue("you","can't","stop","me")
What's happening here?
BIND
Take 2 minutes to look up bind in the documentation
Bind
Bind returns a function with an explicit
this
var person = {
name: "Matt",
sayHi: function(){
setTimeout(function(){
console.log(`${this.name} says hi!`)
}.bind(this),1000)
}
}
Think, Pair, Share - Write out this function
- What is the context of the this.name log without bind? Why?
- What is the context of the this.name log with bind? Why?
Bind
Bind returns a function with an explicit
this
var person = {
name: "Elie",
sayHi: function(){
setTimeout(function(){
console.log(`${this.name} says hi!`)
}.bind(this),1000)
}
}
setTimeout is attached to window!
bind allows us to capture the execution context of sayHi
From the MDN docs
this.x = 9; // this refers to global "window" object
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX();
// returns 9 - The function gets invoked at global scope
// Create a new function with 'this' bound to module
// New programmers might confuse the
// global var x with module's property x
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
Review
What's an execution context?
What is the difference between call and apply?
What does bind return?
This, Call, Apply, Bind
By Matthew Williams
This, Call, Apply, Bind
- 782