To achieve the desired outcome, you may consider utilizing a weak binding technique:
function createWeakBinding(func, object) {
var GLOBAL = this;
return function () {
return func.apply(this === GLOBAL ? object : this, arguments);
};
}
With this approach, you can implement the following functionality:
var user = {
name: 'John',
action: function () {
console.log(this.name);
}
};
var details = {
name: 'details'
};
var actionFunc = createWeakBinding(user.action, details);
actionFunc(); // output details
var actionFunc2 = createWeakBinding(actionFunc, user);
actionFunc2(); //output John
Explore the demo here: http://jsfiddle.net/E98GF/
The issue with traditional binding is that it locks the object assigned to the this
keyword, making it difficult to change. By employing weak binding, we check if the this
object refers to the GLOBAL
object (defaulting to a specific context if not). This allows for more flexibility in defining the execution context.
Alternatively, a simpler solution in your scenario would be:
var user = {
name: 'John',
action: function () {
console.log(this.name);
}
};
var details = {
name: 'details'
};
var actionFunc = user.action.bind(details);
actionFunc(); // output details
var actionFunc2 = user.action.bind(user);
actionFunc2(); //output John
Using bind
directly improves code readability and ensures that calling actionFunc2
triggers user.action
immediately without an intermediate step.