Last active
October 15, 2017 06:38
-
-
Save roryokane/10b7d9f45bdece159431 to your computer and use it in GitHub Desktop.
Summary of this, call, and bind in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// exploring `this` in JavaScript, and `.call` and `.bind` | |
// our cast | |
anna = {name: "Anna"}; | |
zach = {name: "Zach"}; | |
// how `this` works | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this | |
anna.getName = function() { return this.name; }; | |
console.log( anna.getName() ); // "Anna" | |
// `this` refers to `anna` in this case. `anna.name` is "Anna". | |
zach.getName = anna.getName; | |
console.log( zach.getName() ); // "Zach" | |
// With the reassigned function, `this` refers to `zach`. | |
// `this` in a function is the parent at the time of calling, | |
// not the time of definition. | |
// What is `this` in a function with no parent object? | |
var freeGetName = anna.getName; | |
console.log( freeGetName() ); // "" | |
// For a function with no parent object, when run in a browser, `this` is `window`. | |
// `window.name` defaults to "". | |
console.log( this ); // window | |
// Strict mode ("use strict") tries to protect you from this: | |
(function() { | |
"use strict"; | |
console.log( this ); // undefined | |
})(); | |
// But you can’t really rely on it: | |
(function() { | |
"use strict"; | |
console.log( freeGetName() ); // "" (`window.name`) | |
})(); | |
// If a function with no parent is running in strict mode (`"use strict";`), `this` will STILL be `window`. | |
// You would expect it to be `undefined` instead, but both Chrome and Firefox have `this` be `window`. | |
// Maybe it’s something the designers of "use strict" overlooked when defining it, | |
// and now they can’t change it because of backwards compatibility. | |
// how `call` and `apply` work | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply | |
// In all examples on this page, `apply` would do the exact same thing as `call`. | |
// The only difference between `call` and `apply` is how they take extra arguments to call the function with. | |
// The examples on this page don’t use that feature, so I just demonstrate with `call`. | |
// `call` calls the function with `this` being the first argument. | |
// (`call` can also take arguments to pass through, but that’s irrelevant to this example.) | |
console.log( freeGetName.call(zach) ); // "Zach" | |
// It works the same no matter what object the function is currently attached to. | |
console.log( anna.getName.call(zach) ); // "Zach" | |
// how `bind` works | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind | |
// `bind` locks the value of `this` to the passed object. | |
// The returned function will always ignore any other suggestions to use a different value of `this`. | |
zach.annaBoundGetName = anna.getName.bind(anna); | |
console.log( zach.annaBoundGetName() ); // "Anna" – not "Zach" like with `zach.getName` | |
var freeAnnaBoundGetName = anna.getName.bind(anna); | |
console.log( freeAnnaBoundGetName() ); // still "Anna" | |
// Can you re-bind a bound function? | |
var reboundGetName = freeAnnaBoundGetName.bind(zach); | |
console.log( reboundGetName() ); // still "Anna" | |
// No. | |
// how `call` and `bind` interact | |
console.log( zach.annaBoundGetName.call(zach) ); // still "Anna" | |
console.log( freeAnnaBoundGetName.call(zach) ); // still "Anna" | |
// A function resulting from `bind` *always* overrides the value of `this`. | |
// None of assignment to an object, `call`, or `bind` can change `this` again. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment