每个javascript函数都有两个非继承的方法 apply()、 call(),这两个方法的用途相同,都是在特定的作用域中调用函数,直接一点的说法就是改变函数内部的this指针。
this指针介绍 
this表示当前对象的一个引用。
单独使用this时,this默认指向全局对象window。(当前对象是window对象)
console.log(this) // 打印window对象当在浏览器中全局运行函数时,它的this指针同样默认指向全局对象window。(当前对象是window对象)
function fun() {
    console.log(this) // 打印window对象
}当在对象里的方法使用this指针的时候,它指向当前对象。(当前对象是obj对象)
var obj = {
    title: 'fun',
    fun: function() {
        console.log(this) // 打印obj对象
    }
}使用apply()方法 
apply()方法接受两个参数,第一个参数是在其中运行函数的作用域,第二个参数是是一个参数数组,用于向函数中传递参数。
var num = 10
function myFun1(num1, num2) {
    console.log(this.num + num1 + num2)
}
myFun1(1,2)上面的代码定义了全局变量num和全局函数myFun,当运行myFun函数时,将会打印10 + 1 + 2的值,也就是13。
var num = 10
var myObj = {
    num: 20,
    myFun2: function(num1, num2) {
        console.log(this.num + num1 + num2)
    }
}
myObj.myFun2(1,2)上面这串代码,将变量和方法都定义在一个对象里,这样this.num不再是全局的num,而是当前对象中的num,所以结果打印出来的是20 + 1 + 2的值,也就是23。 如果我想在运行myFun1时能够使用myObj中的num怎么办?这里就可以使用apply函数来改变this指向。
myFun1.apply(myObj, [1, 2])使用上面这串代码最终将打印23,说明已经改变了myFun1的this指向。其中的this.num是20。 同样的,也可以在运行myFun2的时候使用全局的变量num,只需要将this指向全局对象window就行。
myObj.myFun2.apply(window, [1, 2])最终打印的结果是13,说明这里的this.num是10。 上面的代码apply函数传参使用参数数组,也就是[1, 2]的形式,分别代表第一第二个参数,如果函数不需要传参数,可以不传apply的第二个参数。
使用call()方法,它与apply()有什么不同? 
call函数的使用方法基本上和apply一样,只是传递参数的方式不一样,apply通过参数数组的形式传参,而call需要把参数一个个都分别传进去。例如将上面的例子改成使用call函数,如下:
myFun1.call(myObj, 1, 2)使用bind()函数绑定this指针 
bind方法同样用于改变this指针,但和apply、call方法不同。apply和call在调用函数后会立即执行,不会保存this改变后的状态。而bind在调用函数后不会立即执行,在改变this指针后返回一个新的函数,供以后使用。
myFun1.apply(myObj, [1, 2]) // 23
myFun1(1, 2) // 13上面的例子中,在myFun1执行apply函数后,其本身并没有改变this指向,在下次执行时还是会变回原来的this。如果想保存this改变后的状态,就需要使用bind函数。
var myFun3 = myFun1.bind(myObj)
myFun3(1, 2) // 23
myFun3(1, 2) // 23