function sum(x,y,z){
return x+y+z;
}
sum.bind(this,1,2,3)();//执行完是6
sum.bind(this,1,2)(3);//同上
这两种写法有什么区别
第一种值永远是6,因为x=1,y=2,z=3的参数值无法改变,sum.bind(this,1,2,3)等价于
function sum(){
var x=1,y=2,z=3;
return x+y+z;
}
第二种可以修改z的值,通过参数传入
sum.bind(this,1,2)
等价于
function sum(z){
var x=1,y=2;
return x+y+z;
}
可以看一下函数柯里化
http://blog.jobbole.com/77956/
这是bind的特性吧。网上还有很多bind在低版本中没实现的兼容
这里MDN上面的polyfill
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP
? this
: oThis || this,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
解决你的问题,其他的不用看,看参数aArgs,bind的时候 定义了aArgs变量,保存了传递的所有参数。
返回的函数里面有个aArgs.concat(Array.prototype.slice.call(arguments)) ,其中concat将调用的传递参数与之前bind的参数拼接
Array.prototype.slice.call(arguments)只是转一个数组可以忽略
function sum(x,y,z){
return x+y+z;
}
sum.bind(this,1,2,3)();
sum.bind(this,1,2)(3);
bind方法创建一个新函数,称为绑定函数,绑定函数会以创建它时传入bind方法的第一个参数作为this,传入bind方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
第一种调用方法相当于:
sum.bind(this,1,2,3)返回的是:
function(){
var x = 1,y = 2, z = 3;
return x + y + z;
}
sum.bind(this,1,2,3)()就相当于:
(function(){
var x = 1,y = 2, z = 3;
return x + y + z;
})()
匿名函数的自调,所以返回的值6
而sum.bind(this,1,2)返回的值是:
function(z){
var x = 1,y = 2;
return x + y + z;
}
所以sum.bind(this,1,2)(3)就相当于:
(function(z){
var x = 1,y = 2;
return x + y + z;
})(3)
匿名函数自调,传入了参数,所以这个参数是随着调用传的值改变。