The bind() Method
The bind() method was added in ESMAScript 5, but it is easy to simulate in ESMAScrpt 3. As its name implies, the primary purpose of bind() is to bind a function to an object. When you invoke the bind() method on a function f and pass an object o,the method returns a new function. Invoking the new function (as a function) invokes the original function f as a method of o. Any arguments you pass to the new function are passed to the original function. For example:
function f(y) { return this.x + y; } // This function need to be bound
var o = { x:1 }; // An object we'll bind to
var g = f.bind(o); // Calling g(x) invokes o.f(x)
g(2); // => 3
It's easy to accomplish this kind of binding with code like the following:
//Return a function that invokes f as a method of o, passing all its arguments.
function bind(f,o) {
if (f.bind) return f.bind(o); // Use the bind method, if there is one.
else return function() { // Otherwise, bind it like this
return f.apply(o, arguments);
};
}
The ECMAScript 5 bind() method does more than just bind a function to an object. It also performs partial application: any arguments you pass to bind() after the first are bound along with the this value. Partial application is a common technique in functional programming and is sometimes called currying. Here are some examples of the bind() method used for partial application:
var sum = function(x,y) { return x + y }; // Return the sum of 2 args
// Create a new function like sum, but with the this value bound to null
// and the 1st argument bound to 1. This new function expects just one arg.
var succ = sum.bind(null,1);
succ(2) // => 3: x is bound to 1, and we pass 2 for the y argument
function f (y,z) { return this.x + y + z }; // Another function that adds
var g = f.bind({x:1},2); // Bind this and y
g(3); // => 6: this.x is bound to 1, y is bound to 2 and z is 3
We can bind the this value and perform partial application in ECMAScript 3. The standard bind() method can be simulated with the code like that shown in Example 8-5.
Note that we save this method as Function.prototype.bind, so that all function objects inherit it. This technique is explained in detail in 9.4
Example 8-5. A Function.bind() method for ECMAScript 3
if (!Function.prototype.bind) {
Function.prototype.bind = function(o /*, args */) {
// Save the this and arguments values into variables so we can
// use them in the nested function below。
var self = this, boundArgs = arguments;
// The return value of the bind() method is a function
return function() {
// Build up an argument list, starting with any args passed
// to bind after the first one, and follow those with all args
// passed to this function.
var args = [], i;
for(i=1; i < boundArgs.length; i++) args.push(boundArgs[i]);
for(i=0; i < arguments.length; i++) args.push(arguments[i]);
// Now invoke self as a method of o, with those arguments
return self.apply(o, args);
};
};
}
Notice that the function returned by this bind() method is a closure that uses the variables self and boundArgs declared in the outer function, even though that inner function has been returned from the outer function and is invoked after the outer function has returned.
The bind() method defined by ECMAScript 5 does have some features that cannot be simulated with ECMAScript 3 code shown above. First, the true bind() methed return a function object with its length property properly set to the arity of the bound function minus the number of bound arguments (but not less than zero). Second, the ECMAScript 5 bind() method can be used for partial application of constructor functions. If the function returned by bind() is used as a constructor, the this passed to bind() is ignored, and the original function is invoked as a constructor, with some arguments already bound. Functions returned by the bind() method do not have a prototype property (the prototype property of rgular functions cannot be deleted) and objects created when these bound functions are used as constructors inherit from the prototype of the original, unbound constructor. Also, a bound constructor works just like the unbound constructor for the purposes of the instanceof operator.
最新文章
- 阿里无线前端性能优化指南 (Pt.1 加载优化)
- AP是什么
- html5新特性
- suse linux中apache+php服务器安装
- LeetCode23 Merge k Sorted Lists
- ThinkPHP框架的网站url重写
- js 获取节点
- 重写String类,也有些区别,供参考
- 通过Orchard认识的Autofac
- C语言之进制
- 2016 Technology
- JVM学习001通过实例总结Java虚拟机的运行机制
- JavaScript享元模式
- Ubuntu 16.04 LTS今日发布
- Linux C Socket简单实例与详细注释
- 限流redis+lua
- Zabbix (五)
- Python hashlib and hmac
- 学习BOS物流项目第十天
- 03-04_配置并启动Managed Server(受管服务器)