Function Bind provides a robust implementation of Function.prototype.bind for JavaScript environments that don't natively support it, including older versions of Internet Explorer, PhantomJS, and Node.js. The library offers a comprehensive polyfill that handles function binding with proper argument handling, context preservation, and prototype chain maintenance.
npm install function-bind// Get the polyfill (uses native bind if available, otherwise polyfill)
var functionBind = require("function-bind");For direct access to the implementation:
// Always use the polyfill implementation
var bindImplementation = require("function-bind/implementation");var functionBind = require("function-bind");
// Replace the native bind (common polyfill pattern)
Function.prototype.bind = functionBind;
// Now you can use bind on any function
var obj = { name: "Alice" };
var greet = function(greeting) {
return greeting + ", " + this.name + "!";
};
var boundGreet = greet.bind(obj, "Hello");
console.log(boundGreet()); // "Hello, Alice!"Creates a new function with a specified this context and optionally pre-bound arguments. This is the main functionality that polyfills Function.prototype.bind.
/**
* Main export - returns native Function.prototype.bind if available, otherwise the polyfill
* @returns {Function} The bind function (native or polyfill)
*/
module.exports = Function.prototype.bind || implementation;/**
* Polyfill implementation of Function.prototype.bind
* @param {any} that - The value to be passed as the this parameter to the target function
* @param {...any} [args] - Arguments to prepend to arguments provided to the bound function
* @returns {Function} A new bound function with the specified this value and initial arguments
* @throws {TypeError} If called on a non-function value with message "Function.prototype.bind called on incompatible [value]"
*/
function bind(that) { /* additional arguments accessed via arguments object */ }Usage Examples:
var functionBind = require("function-bind");
// Basic context binding
var obj = { multiplier: 10 };
var multiply = function(x) { return x * this.multiplier; };
var boundMultiply = functionBind.call(multiply, obj);
console.log(boundMultiply(5)); // 50
// Partial application with context binding
var calculator = { base: 100 };
var add = function(a, b) { return this.base + a + b; };
var addTen = functionBind.call(add, calculator, 10);
console.log(addTen(5)); // 115 (100 + 10 + 5)
// Constructor behavior
var Person = function(name) { this.name = name; };
Person.prototype.greet = function() { return "Hello, " + this.name; };
var BoundPerson = functionBind.call(Person, null, "Default");
var person = new BoundPerson(); // name will be "Default"
console.log(person.greet()); // "Hello, Default"
console.log(person instanceof Person); // true
console.log(person instanceof BoundPerson); // trueFor cases where you want to always use the polyfill implementation rather than the native version.
/**
* Direct access to the polyfill implementation
* Available via require("function-bind/implementation")
* This is the same bind function that would be used as the polyfill
* @param {any} that - The value to be passed as the this parameter
* @param {...any} [args] - Arguments to prepend to call-time arguments
* @returns {Function} A new bound function
* @throws {TypeError} If called on a non-function value
*/
var implementation = require("function-bind/implementation");
// implementation is the bind function: function bind(that) { ... }Usage Example:
var bindImpl = require("function-bind/implementation");
var context = { value: 42 };
var fn = function(x) { return this.value + x; };
var boundFn = bindImpl.call(fn, context, 10);
console.log(boundFn(5)); // 57 (42 + 10 + 5)The bound function maintains the specified this context when called:
var obj = { name: "test" };
var fn = function() { return this.name; };
var bound = functionBind.call(fn, obj);
console.log(bound()); // "test"Arguments can be pre-bound and will be prepended to call-time arguments:
var add = function(a, b, c) { return a + b + c; };
var addFive = functionBind.call(add, null, 5);
console.log(addFive(10, 15)); // 30 (5 + 10 + 15)When the bound function is called with new, it properly handles constructor behavior:
var Constructor = function(x) { this.value = x; };
var BoundConstructor = functionBind.call(Constructor, null, 42);
var instance = new BoundConstructor();
console.log(instance.value); // 42
console.log(instance instanceof Constructor); // true
console.log(instance instanceof BoundConstructor); // trueThe bound function's length property correctly reflects the remaining parameters:
var fn = function(a, b, c) { return a + b + c; };
console.log(fn.length); // 3
var boundOne = functionBind.call(fn, null, 1);
console.log(boundOne.length); // 2
var boundTwo = functionBind.call(fn, null, 1, 2);
console.log(boundTwo.length); // 1
var boundAll = functionBind.call(fn, null, 1, 2, 3);
console.log(boundAll.length); // 0The implementation throws appropriate errors for invalid usage:
// Throws TypeError: Function.prototype.bind called on incompatible [object String]
try {
functionBind.call("not a function");
} catch (error) {
console.log(error instanceof TypeError); // true
}This polyfill is specifically designed for environments that lack native Function.prototype.bind:
The polyfill provides identical behavior to the native implementation as specified in ECMAScript 5.