call、apply、 bind


windowOS安装mysql5+ 解压缩版之教程

call()

语法:

1
fun.call(thisArg[,args1[,args[,...]]])

thisArg: fun函数运行时指定的this值,可能的值为:

  • 不传,或者传nullundefined、this指向window对象
  • 传递另一个函数的函数名fun2,this指向fun2的引用
  • 值为原始值(数字、字符串、布尔值),this会指向该原始值的自动包装对象,如String、Number、Boolean
  • 传递一个对象,函数中的this指向这个对象

    例如:

1
2
3
4
5
function  a () {
console.log(this);
}
function b(){}
a.call(b); // function b(){}

经常会看到这种使用情况:

1
2
3
4
function list() {
return Array.prototype.slice.call(argusments)
}
list(1,2,3); // [1,2,3]

为什么会实现这样的功能将argument转成数组?首先,call了之后,this指向了所传进去的arguments,我们可以假设slice方法的内部是这样子的:创建一新数组,然后for循环遍历this,将this[i]一个个的赋值给新数组,最后返回该数组。因此也就可以理解能实现这样的功能了。

apply()

语法:

1
2
3
// Chrome 14 以及 Internet Explorer 9 仍然不接受类数组对象。
// thisArg的可能值和call一样
fun.apply(thisArg[, argsArray])

例如:

1
2
3
var numbers = [5,6,2,3,7];
var max = Math.max.apply(null, numbers);
console.log(max); // 7

平时Math.max 只能这样子用:Math.max(5,6,2,3,7);
利用apply的第二个参数是数组的特性,从而能够简便的从数组中找到最大值

bind

语法:

1
fun.bind(thisArg[,args1[,...]])

bind()方法会创建一个新函数,称为绑定函数
bind是ES5新增的一个方法,不会执行对应的函数(call或apply会自执行对应的函数),而是返回对绑定函数的引用

当调用这个绑定函数时,thisArgs参数作为this,第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
简单地说,bind会产生一个新的函数,这个函数可以有预设的参数。

1
2
3
4
5
6
function list(){
return Array.prototype.slice.call(arguments);
}
var lendingThirtysevenList = list.bind(undefined, 37);
var list = lendingThirtysevenList (1,2,3);
console.log(list); // [37,1,2,3]

bind调用简单

把类数组换成真正的数组,bind能够更简单地使用:

  • apply用法
1
2
var slice =  Array.prototype.slice;
slice.apply(arguments); // 类似对象的方法那样调用
  • bind用法
1
2
3
4
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.apply.bind(unboundSlice);
// ...
slice(arguments); // 直接调用,简单

三者的区别:

相同之处:改变函数体内 this 的指向。
不同之处:

call、apply的区别:接受参数的方式不一样。
bind:不立即执行。而apply、call 立即执行。