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

  1. What is the context of the this.name log without bind? Why?
  2. 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

  • 765