function foo(arg1, arg2){console.log(`I am ${this.bar}. I am ${arg1}. I am ${arg2}`)};
foo(); // I am undefined. I am undefined. I am undefined
bindFoo = foo.bind({bar: 'bar'}, 'argument1', 'argument2'); // bind but call later
bindFoo(); // I am bar. I am argument1. I am argument2
foo.call({bar: 'bar'}, 'argument1', 'argument2'); // call immediately, args passed one by one
// I am bar. I am argument1. I am argument2
foo.apply({bar: 'bar'}, ['argument1', 'argument2']); // call immediately, args passed as an array
// I am bar. I am argument1. I am argument2