Function.prototype.apply()
apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数
apply接收两个参数,第一个参数是this的指向,第二个参数是函数接受的参数,以数组的形式传入,且当第一个参数为null、undefined的时候,默认指向window(在浏览器中),使用apply方法改变this指向后原函数会立即执行,且此方法只是临时改变thi指向一次
var name="martin";
var obj={
name:"lucy",
say:function(year,place){
console.log(this.name+" is "+year+" born from "+place);
}
};
var say=obj.say;
setTimeout(function(){
say.apply(obj,["1996","China"])
} ,0); //lucy is 1996 born from China this改变指向了obj
say("1996","China") //martin is 1996 born from China this指向window,说明apply只是临时改变一次this指向
Function.prototype.bind()
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用
bind方法实现了更改原函数内部的this指向并返回了一个新函数出来
function hello(x, y) {
console.log(this, x, y)
};
hello.bind({name: 'demo'})(1, 2); // {name: 'demo'} 1 2
hello.bind({name: 'demo'}, 1, 2)(); // {name: 'demo'} 1 2
console.log(hello.bind({}).name) // bound hello //使用bind()的name前面都要加bound,后面才是方法的名字
console.log((function() {}).bind({}).name) // bound //function没有名字,直接输出bound
bind方法第一参数也是this的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入,call则必须一次性传入所有参数),但是它改变this指向后不会立即执行,而是返回一个永久改变this指向的函数
var arr=[1,10,5,8,12];
var max=Math.max.bind(null,arr[0],arr[1],arr[2],arr[3])
console.log(max(arr[4])); //12,分两次传参
Function.prototype.call()
call() 方法使用一个指定的 this值和单独给出的一个或多个参数来调用一个函数
call方法的第一个参数也是this的指向,后面传入的是一个参数列表(注意和apply传参的区别)。当一个参数为null或undefined的时候,表示指向window(在浏览器中),和apply一样,call也只是临时改变一次this指向,并立即执行
var arr=[1,10,5,8,3];
console.log(Math.max.call(null,arr[0],arr[1],arr[2],arr[3],arr[4])); //10
三者区别
- 三者都可以改变函数的
this
对象指向 - 三者第一个参数都是
this
要指向的对象,如果如果没有这个参数或参数为undefined
或null
,则默认指向全局window
- 三者都可以传参,但是
apply
是数组,而call
是参数列表,且apply
和call
是一次性传入参数,而bind
可以分为多次传入 bind
是返回绑定this之后的函数,apply
、call
是立即执行