Giter VIP home page Giter VIP logo

js-advanced-functions-context-and-explicit-setting's Introduction

JavaScript Advanced Functions: Context and Explicit Setting

Learning Goals

  • Explicitly override context with call and apply
  • Explicitly lock context for a function with bind

Introduction

In the previous lesson, we learned that when we invoke functions JavaScript will make a context available inside the function. That context will be set to "whatever's to the left of the dot" or, when there's nothing to the left of the dot, the global object.

JavaScript provides other means for specifying what we want the context to be. These are the explicit methods of setting execution context: call, apply, and bind.

Explicitly Override Context with call and apply

The methods on functions called call and apply allow us to override the execution context.

Let's think back to a previous lesson and recall working with records. We'll invoke the functions in a familiar way, but also show how we could achieve the equivalent behavior using call or apply.

let asgardianBrothers = [
  {
    firstName: "Thor",
    familyName: "Odinsson"
  },
  {
    firstName: "Loki",
    familyName: "Laufeysson-Odinsson"
  }
]

function intro(person, line) {
  return `${person.firstName} ${person.familyName} says: ${line}`
}

function introWithContext(line){
  return `${this.firstName} ${this.familyName} says: ${line}`
}

let phrase = "I like this brown drink very much, bring me another!"
intro(asgardianBrothers[0], phrase) //=> Thor Odinsson says: I like this brown drink very much, bring me another!
intro(asgardianBrothers[0], phrase) === introWithContext.call(asgardianBrothers[0], phrase) //=> true
intro(asgardianBrothers[0], phrase) === introWithContext.apply(asgardianBrothers[0], [phrase]) //=> true

let complaint = "I was falling for thirty minutes!"
intro(asgardianBrothers[1], complaint) === introWithContext.call(asgardianBrothers[1], complaint) //=> true
intro(asgardianBrothers[1], complaint) === introWithContext.apply(asgardianBrothers[1], [complaint]) //=> true

When we first wrote a record-oriented program, we wrote functions in the style of intro. They took the record as an argument. In fact, if we look at the solution branch for the previous lesson, we'll see that multiple functions have the same first parameter: employee, the record. Your solution probably has a similar repetition.

function createTimeInEvent(employee, dateStamp){ /* */ }
function createTimeOutEvent(employee, dateStamp){ /* */ }
function hoursWorkedOnDate(employee, soughtDate){ /* */ }

What if we told JavaScript that instead of the record being a parameter (in addition to a phrase), it could be assumed as a context and thus accessible via this. That's what we're doing with the function introWithContext as invoked with either call or apply.

The introWithContext function expects only a catchphrase as an argument. Both call and apply take a thisArg argument as their first argument (see their documentation for further clarification): that argument becomes the this inside the function. In the case of call, anything after the thisArg gets passed to the function like arguments inside of a (). In the case of apply, the contents in the Array get destructured and passed to the function like arguments inside of a ().

ES6 ALERT: Some might wonder: if we have destructuring of Arrays, why do we need both call and apply since a destructured Array, as required by apply could simply be destructured and fed to call. Destructuring is a relatively new arrival to JavaScript, so before then JavaScript had two separate methods.

Explicitly Lock Context For a Function With bind

Let's suppose that we wanted to create the introWithContext function, but have it permanently bound to asgardianBrothers[0]. As the adjective "bound" suggests, we use bind:

let asgardianBrothers = [
  {
    firstName: "Thor",
    familyName: "Odinsson"
  },
  {
    firstName: "Loki",
    familyName: "Laufeysson-Odinsson"
  }
]
function introWithContext(line){
  return `${this.firstName} ${this.familyName} says: ${line}`
}

let thorIntro = introWithContext.bind(asgardianBrothers[0])
thorIntro("Hi, Jane") //=> Thor Odinsson says: Hi, Jane
thorIntro("I love snakes") //=> Thor Odinsson says: I love snakes

The bind method returns a function that needs to be called, but wherever the function that bind was called on had a this reference, the this is "hard set" to what was passed into bind.

Conclusion

To sum up the explicit overrides:

  1. Execution context is set in a function by invoking call on the function and passing, as the first argument, a thisArg which is accessed via this in the function. Additional parameters to the function are listed after ,
  2. Execution context is set in a function by invoking apply on the function and passing, as first argument, a thisArg which is accessed via this in the function. Additional parameters to the function are stored in the second argument: an Array containing arguments to the function.
  3. Execution context can be locked in a function by invoking bind on it and passing it a thisArg. The bind function makes a copy of the functionality of its function but with all the this stuff locked in place and returns that function. That new function can have arguments passed to it during its call with () as usual.

Resources

js-advanced-functions-context-and-explicit-setting's People

Contributors

ihollander avatar rrcobb avatar sylwiavargas avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.