how-jest-mocking-works icon indicating copy to clipboard operation
how-jest-mocking-works copied to clipboard

quick question: what is the purpose of `bind()` in `tracks.push.bind(tracks)` ??

Open ApolloTang opened this issue 6 years ago • 1 comments
trafficstars

https://github.com/kentcdodds/how-jest-mocking-works/blob/master/tracker.js#L2

ApolloTang avatar May 24 '19 05:05 ApolloTang

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 avatar May 06 '20 11:05 apexskier

@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")

ApolloTang avatar Mar 03 '23 00:03 ApolloTang

Thanks @apexskier. closing this issue now

ApolloTang avatar Mar 03 '23 00:03 ApolloTang