You need to use bind (or a similar approach) when:
- The function is a traditional (functionkeyword) function or method (in aclassor object literal), and
- That function will be called either in a way that doesn't set thisexplicitly or that sets it to an incorrect value
The reason is that with a traditional function or method, the value of this is set by the caller, not a part of the function itself. (Details here and here.)
For example, consider:
const obj = {
    method() {
        console.log(this === obj);
    }
};
Now, when we do obj.method(), we're using syntax (calling the result of a property accessor operation) to specify what this will be, so:
obj.method();
// => true
But suppose we do this:
const m = obj.method;
Now, just calling m() will set this to the default this (undefined in strict mode, the global object in loose mode):
m();
// => false
Another way we can explicitly set this for the call is via call (and its cousin apply):
m.call(obj);
// => true
Some functions that call callbacks let you specify what this to use. forEach does, as an argument just after the callback:
[1].forEach(m, obj);
//          ^  ^^^---- the value to use as `this` in callback
//           \-------- the callback to call
// => true
Here's a live example of those:
const obj = {
    method() {
        console.log(this === obj);
    }
};
obj.method();
// => true, `this` was set to `obj` because you did the call on the
// result of a property accessor
const m = obj.method;
m();
// => false, `this` was the default `this` used when `this` isn't
// specified explicitly via syntax or `call`
m.call(obj);
// => true, `this` was explicitly set via `call`
[1].forEach(m, obj);
// => true, `this` was explicitly set via `forEach`'s `thisArg` argument
 
 
So any time you have a function (such as the callback of a forEach, or an event handler), you need bind or a similar mechanism to ensure that the correct this is used.
This isn't true for some other kinds of functions, just traditional (function keyword) functions and methods (such as obj.method above). An arrow function closes over this instead of using the one supplied by the caller, and a bound function (result of using bind) has this bound to it and so ignores any this supplied by the caller.