Lodash _.bind on ES6 Arrow Functions Explained
Applying the Lodash _.bind method to an ES6 arrow
function will fail to alter the function's execution context
(this), leaving it permanently bound to its enclosing
lexical scope. While the context binding is silently ignored without
throwing a runtime error, any additional arguments passed to
_.bind will still be successfully partially applied.
Understanding this behavior is critical for avoiding subtle state bugs
when working with modern JavaScript and utility libraries.
Lexical this vs.
_.bind
In ECMAScript 2015 (ES6), arrow functions were designed with lexical
scoping for this. Unlike traditional function
declarations or expressions, arrow functions do not have their own
this binding; instead, they capture the this
value of the enclosing execution context at the moment they are
defined.
Lodash's _.bind method operates similarly to the native
Function.prototype.bind. Under the hood, it attempts to set
the target function's context to the specified thisArg.
However, JavaScript specifications mandate that an arrow function's
lexical this cannot be overridden by bind,
call, or apply. Consequently,
_.bind cannot reassign the context of an arrow
function.
Silent Failure of Context Binding
When you pass an arrow function to _.bind, JavaScript
does not throw a TypeError or warning. The operation
executes normally, but the specified thisArg is completely
disregarded:
const user = { name: 'Alice' };
const greet = () => {
return `Hello, ${this.name}`;
};
const boundGreet = _.bind(greet, user);
// Output depends on the outer scope, not 'user'
console.log(boundGreet()); // "Hello, undefined" (in strict/module scope)In this scenario, greet remains bound to the outer scope
(such as window or globalThis), and passing
user to _.bind has no effect.
Partial Application Still Works
Although context binding fails, _.bind also serves to
partially apply arguments. If you provide additional parameters to
_.bind, Lodash will correctly prepend those arguments to
subsequent calls of the arrow function:
const add = (a, b) => a + b;
// Context is ignored, but 'a' is bound to 5
const addFive = _.bind(add, null, 5);
console.log(addFive(10)); // 15Best Practices
To avoid unexpected behavior when using Lodash with arrow functions:
- Use standard function expressions for dynamic
contexts: If a function relies on a dynamic
thisthat needs to be configured at runtime, define it using thefunctionkeyword rather than an arrow function. - Use
_.partialfor argument pre-filling: If the goal is strictly argument currying or partial application on an arrow function, use Lodash's_.partialinstead of_.bindto make the intent clear and avoid confusion regardingthis.