Upgrade to Pro — share decks privately, control downloads, hide ads and more …

this, call, and bind in JavaScript

this, call, and bind in JavaScript

An explanation through examples of `this` in JavaScript and some functions that manipulate it.

The downloadable PDF version of the slides includes links to documentation on the final summary slide. Speaker Deck’s previewer doesn’t support clicking on links.

Presented at:
http://www.meetup.com/Hoboken-Ruby-On-Rails-Meetup/events/225002095/ on 2015-09-22
http://www.meetup.com/nycruby/events/224763407/ on 2015-11-18

Rory O’Kane

November 18, 2015
Tweet

Other Decks in Programming

Transcript

  1. How this works var anna = {name: "Anna"}; var zach

    = {name: "Zach"}; ! anna.getName = function() { return this.name; };
  2. How this works var anna = {name: "Anna"}; var zach

    = {name: "Zach"}; ! anna.getName = function() { return this.name; }; ! console.log( anna.getName() ); // 㱺 ???
  3. How this works var anna = {name: "Anna"}; var zach

    = {name: "Zach"}; ! anna.getName = function() { return this.name; }; ! console.log( anna.getName() ); // 㱺 "Anna" // this is the parent object – anna.
  4. How this works var anna = {name: "Anna"}; var zach

    = {name: "Zach"}; ! anna.getName = function() { return this.name; };
  5. How this works var anna = {name: "Anna"}; var zach

    = {name: "Zach"}; ! anna.getName = function() { return this.name; }; ! zach.getName = anna.getName; ! console.log( zach.getName() ); // 㱺 ???
  6. How this works var anna = {name: "Anna"}; var zach

    = {name: "Zach"}; ! anna.getName = function() { return this.name; }; ! zach.getName = anna.getName; ! console.log( zach.getName() ); // 㱺 "Zach"
  7. Summary of normal this • anna.getThis() 㱺 anna • zach.getThis()

    㱺 zach • anna.getName() 㱺 "Anna" • zach.getName() 㱺 "Zach"
  8. How this works anna.getName = function() { return this.name; };

    ! var freeGetName = anna.getName; ! console.log( freeGetName() ); // 㱺 ???
  9. How this works anna.getName = function() { return this.name; };

    ! var freeGetName = anna.getName; ! console.log( freeGetName() ); // 㱺 "" // In a browser, this is window. // window.name defaults to "".
  10. How global this works // this in the global scope

    // (in a browser) console.log( this ); // 㱺 ???
  11. How global this works // this in the global scope

    // (in a browser) console.log( this ); // 㱺 window
  12. How global this works var freeGetThis = function() { return

    this; }; ! console.log( freeGetThis() ); // 㱺 ???
  13. How global this works var freeGetThis = function() { return

    this; }; ! console.log( freeGetThis() ); // 㱺 window
  14. How global this works var freeGetThis = function() { return

    this; }; ! (function() { "use strict"; console.log( freeGetThis() ); })(); // 㱺 ???
  15. How global this works var freeGetThis = function() { return

    this; }; ! (function() { "use strict"; console.log( freeGetThis() ); })(); // 㱺 window // apparently not a bug – happens in both Chrome and Firefox
  16. How global this works anna.getName = function() { return this.name;

    }; ! var freeGetName = anna.getName; ! (function() { "use strict"; console.log( freeGetName() ); })(); // 㱺 ???
  17. How global this works anna.getName = function() { return this.name;

    }; ! var freeGetName = anna.getName; ! (function() { "use strict"; console.log( freeGetName() ); })(); // 㱺 "" (window.name)
  18. Summary of global this • this 㱺 window • freeGetThis()

    㱺 window • strict mode this 㱺 undefined • strict mode freeGetThis() 㱺 window
  19. How call/apply work addNumbers(1, 2, 3); ! // call takes

    a new value for this addNumbers.call(undefined, 1, 2, 3) );
  20. How call/apply work addNumbers(1, 2, 3); ! // call takes

    a new value for this addNumbers.call(undefined, 1, 2, 3) ); ! // apply lets you use an array for arguments numbers = [1, 2, 3]; addNumbers.apply(undefined, numbers) );
  21. How call/apply work anna.getName = function() { return this.name; };

    ! var freeGetName = anna.getName; ! console.log( freeGetName.call(zach) );
  22. How call/apply work anna.getName = function() { return this.name; };

    ! var freeGetName = anna.getName; ! console.log( freeGetName.call(zach) ); // = console.log( freeGetName.apply(zach) );
  23. How call/apply work anna.getName = function() { return this.name; };

    ! var freeGetName = anna.getName; ! console.log( freeGetName.call(zach) ); // 㱺 ???
  24. How call/apply work anna.getName = function() { return this.name; };

    ! var freeGetName = anna.getName; ! console.log( freeGetName.call(zach) ); // 㱺 "Zach"
  25. How call/apply work anna.getName = function() { return this.name; };

    ! console.log( anna.getName.call(zach) ); // 㱺 ???
  26. How call/apply work anna.getName = function() { return this.name; };

    ! console.log( anna.getName.call(zach) ); // 㱺 "Zach"
  27. How bind works function add(x, y) { return x +

    y; } add(2, 2); // 㱺 4 ! // bind returns a new function that // remembers values for this and arguments var addSix = add.bind(undefined, 6) ); addSix(2); // 㱺 8
  28. How bind works anna.getName = function() { return this.name; };

    ! var freeAnnaBoundGetName = anna.getName.bind(anna); ! console.log( freeAnnaBoundGetName() ); // 㱺 ???
  29. How bind works anna.getName = function() { return this.name; };

    ! var freeAnnaBoundGetName = anna.getName.bind(anna); ! console.log( freeAnnaBoundGetName() ); // 㱺 "Anna"
  30. How bind works anna.getName = function() { return this.name; };

    ! zach.annaBoundGetName = anna.getName.bind(anna); ! console.log( zach.annaBoundGetName() ); // 㱺 ???
  31. How bind works anna.getName = function() { return this.name; };

    ! zach.annaBoundGetName = anna.getName.bind(anna); ! console.log( zach.annaBoundGetName() ); // 㱺 "Anna"
  32. How bind works anna.getName = function() { return this.name; };

    ! var freeAnnaBoundGetName = anna.getName.bind(anna); ! var reboundGetName = freeAnnaBoundGetName.bind(zach); ! console.log( reboundGetName() ); // 㱺 ??? // Can you re-bind a bound function?
  33. How bind works anna.getName = function() { return this.name; };

    ! var freeAnnaBoundGetName = anna.getName.bind(anna); ! var reboundGetName = freeAnnaBoundGetName.bind(zach); ! console.log( reboundGetName() ); // 㱺 "Anna" // Can you re-bind a bound function? No.
  34. How bind and
 call/apply interact anna.getName = function() { return

    this.name; }; ! zach.annaBoundGetName = anna.getName.bind(anna); ! console.log( zach.annaBoundGetName.call(zach) ); // 㱺 ???
  35. How bind and
 call/apply interact anna.getName = function() { return

    this.name; }; ! zach.annaBoundGetName = anna.getName.bind(anna); ! console.log( zach.annaBoundGetName.call(zach) ); // 㱺 "Anna"
  36. How bind and
 call/apply interact anna.getName = function() { return

    this.name; }; ! var freeAnnaBoundGetName = anna.getName.bind(anna); ! console.log( freeAnnaBoundGetName.call(zach) ); // 㱺 ???
  37. How bind and
 call/apply interact anna.getName = function() { return

    this.name; }; ! var freeAnnaBoundGetName = anna.getName.bind(anna); ! console.log( freeAnnaBoundGetName.call(zach) ); // 㱺 "Anna"
  38. Summary • this refers to the function’s parent object at

    the time of calling (not the time of definition). • call/apply can change the value of this for a call, with their first parameter. • bind permanently overrides the value of this in the returned function.