说明
每个函数都包含两个非继承而来的方法,call()和apply(),其作用都是用来改变函数的执行环境。
call/apply/bind方法的来源
call、apply和bind方法其实都是继承自function.prototype中,属于实例方法。
console.log(Function.prototype.hasOwnProperty('call'));
console.log(Function.prototype.hasOwnProperty('apply'));
console.log(Function.prototype.hasOwnProperty('bind'));
上面代码中,返回的全是true,表明三种方法都是继承自Function.prototype中。普通的对象、函数和数组都继承了Function.prototype对象中的三个方法,所以这三个方法在对象、函数和数组中都能使用。
三者的异同
- call、apply、bind这三个方法的第一个参数都是this的指定对象,从第二个参数开始出现差别。
- call的参数是直接放进去的,第二个第三个第n个参数都是用逗号分隔,直接放到后面。例如:obj.myFun.call ( db , ‘成都’ , … , ‘武汉’ )
- apply的参数除了第一个以外,要全部放在一个数组里面传进去。例如:obj.myFun.apply ( db , [ ‘成都’ , ‘武汉’ ])
- bind除了返回时函数以外,它和call的参数一样。
- 三者的参数不限定是string类型,允许是各种类型,包括函数、object等。
call()方法
call()方法调用一个函数,其具有一个指定的this值和分别提供的参数。
第一个参数:在fun函数运行时指定的this值。如果指定了null或undefined则内部this指向window。后面的参数:指定的参数列表。
apply()方法
apply方法调用一个函数,其具有一个指定的this值,以及作为一个数组(或者是类似数组的对象)提供的参数。apply和call非常相似,不同之处在于提供参数的方式。apply()使用参数数组而不是一组参数列表。
//call和apply
var color = 'red';
var o = {
color: 'blue'
}
function sayColor() {
console.log(this.color);
}
sayColor.call(this) //red
sayColor.call(window) //red
sayColor.call(o) //blue
bind()方法
bind方法用于指定函数内部的this指向(执行时所在的作用域),然后返回一个新函数。bind方法并非立即执行一个函数。
window.color = 'red'
var o = {
color: 'blue'
}
function sayColor() {
console.log(this.color)
}
var bindSayColor = sayColor.bind(o);
bindSayColor() // => blue