soft bind this.
// soft bind this
'use strict';
if (!Function.prototype.softBind) {
Function.prototype.softBind = function (obj) {
var fn = this;
var curried = [].slice.call(arguments, 1);
var bound = function bound() {
return fn.apply(!this || this === (window || global) ? obj : this, curried.concat(arguments));
};
bound.prototype = Object.create(fn.prototype);
return bound;
};
}
// example
function foo() {
console.log('name: ' + this.name);
}
var obj_1 = { name: 'obj_1' },
obj_2 = { name: 'obj_2' },
obj_3 = { name: 'obj_3' };
var foo_binded = foo.softBind(obj_1);
foo_binded(); // 'obj_1'
obj_2.foo = foo.softBind(obj_1);
obj_2.foo(); // 'obj_2'
foo_binded.call(obj_3); // 'obj_3'
setTimeout(obj_2.foo, 10); // 'obj_1'