how-jest-mocking-works
how-jest-mocking-works copied to clipboard
quick question: what is the purpose of `bind()` in `tracks.push.bind(tracks)` ??
https://github.com/kentcdodds/how-jest-mocking-works/blob/master/tracker.js#L2
The bind function makes a new "anonymous" function with a specific this in scope. In this case, the array push method uses this to know what array to mutate. When you call foo.method() method knows to set this to foo, but this doesn't work when method is stored without that context.
You can run this code in your browser's dev console to play around with the behavior:
const tracks = []
// > undefined
const pushUnbound = tracks.push
// > undefined
const pushBound = tracks.push.bind(tracks)
// > undefined
pushUnbound("unbound")
// VM858:1 Uncaught TypeError: Cannot convert undefined or null to object
// at push (<anonymous>)
// at <anonymous>:1:1
pushBound("bound")
// > 1
tracks
// > ["bound"]
const other = []
// > undefined
const pushBoundToOther = tracks.push.bind(other)
// > undefined
pushBoundToOther("other")
// > 1
tracks
// > ["bound"]
other
// > ["other"]
In pushUnbound("unbound"), this is undefined, so it crashes.
Notice that in pushBoundToOther you can bind to a totally different array and that other array will be modified!
@apexskier, I just saw this (2 years late). Thank you.
After reading your explanation, I understand now!
Calling:
pushUnbound("unbound")
is same as calling:
Array.prototype.push("unbound")
in isolation; where the method push is not associated with anything. Using bind, we can make the association:
Array.prototype.push.bind(someArray)("unbound")
Thanks @apexskier. closing this issue now