JavaScript中的每一个function对象都会有call、apply和bind方法,都是Function的原型上的方法,每个函数都是Function的实例,所以每个函数都可以调用原型上的这几个方法
三者最基本的作用都是改变函数中this的指向
call和apply唯一的区别是call中参数不限制,而apply只有两个参数,call中传参是一个个传,apply是通过数组来传参,传参数在3个及3个以内call和apply差不多,如果超过3个call的性能要比apply好一些(jquery源码中也提到call的性能要优于apply,所以在开发的时候尽量使用call)

/*apply()方法*/
function.apply(thisObj[, argArray])

/*call()方法*/
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);

而bind只是进行预处理,并不立即执行函数

call:
call 方法第一个参数是要绑定给this的值,后面传入的是一个参数列表。当第一个参数为null、undefined的时候,默认指向window。

var arr = [1, 2, 3, 89, 46]
var max = Math.max.call(null, arr[0], arr[1], arr[2], arr[3], arr[4])//89

可以这么理解:

obj1.fn() 
obj1.fn.call(obj1);

fn1()
fn1.call(null)

f1(f2)
f1.call(null,f2)

看一个例子:

var obj = {
    message: 'My name is: '
}

function getName(firstName, lastName) {
    console.log(this.message + firstName + ' ' + lastName)
}
getName.call(obj, 'Dot', 'Dolby')

apply
apply接受两个参数,第一个参数是要绑定给this的值,第二个参数是一个参数数组。当第一个参数为null、undefined的时候,默认指向window。

var arr = [1,2,3,89,46]
var max = Math.max.apply(null,arr)//89

可以这么理解

obj1.fn() 
obj1.fn.apply(obj1);

fn1()
fn1.apply(null)

f1(f2)
f1.apply(null,f2)