Skip to content

Instantly share code, notes, and snippets.

@colingourlay
Created August 13, 2014 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colingourlay/6fae0e032aef6a05e9e7 to your computer and use it in GitHub Desktop.
Save colingourlay/6fae0e032aef6a05e9e7 to your computer and use it in GitHub Desktop.
Bind a function, with a reference to its target
/* Raynos' function.bind module, edited to add __target__ property */
/* Original: https://github.com/Raynos/function-bind/blob/master/index.js */
var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
var slice = Array.prototype.slice;
var toStr = Object.prototype.toString;
var funcType = '[object Function]';
module.exports = bind;
function bind(that) {
var target = this;
if (typeof target !== 'function' || toStr.call(target) !== funcType) {
throw new TypeError(ERROR_MESSAGE + target);
}
var args = slice.call(arguments, 1);
var binder = function () {
if (this instanceof bound) {
var result = target.apply(
this,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return this;
} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);
}
};
var boundLength = Math.max(0, target.length - args.length);
var boundArgs = [];
for (var i = 0; i < boundLength; i++) {
boundArgs.push("$" + i);
}
var bound = Function("binder", "return function (" + boundArgs.join(",") + "){return binder.apply(this,arguments)}")(binder);
if (target.prototype) {
function Empty() {}
Empty.prototype = target.prototype;
bound.prototype = new Empty();
Empty.prototype = null;
}
bound.__target__ = target; // This is the only line I added - Colin
return bound;
}
var bind = require('bind');
function plus(x) {
return this + x;
}
plus.call(1, 2); // > 3
var twoPlus = bind.call(plus, 2);
twoPlus(3) // > 5
twoPlus.__target__; // "function plus(x) { ... }"
twoPlus.__target__.call(3, 4); // 7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment