call、apply、bind主要是用来改变this的重指向。
this对象是在运行时基于函数的执行环境绑定的,全局的环境中this等价于window,而函数被作为对象的方法调用时,this就会等价于当前对象。匿名函数本身执行环境带有全局性,所以匿名函数的this通常指向window。
例子:
var variable = "全局变量";
function output (){
var variable = "局部变量";
console.log(this.variable);
}
output(); // 打印全局变量
output方法的执行看做是window.output的执行,属于window的方法所以this是执行window。则this.variable获取的是window.variable。这也就是为什么打印全局变量的原因。
例子:
var outputagain = {
variable: "局部变量",
output: function(){
console.log(this.variable);
}
}
outputagain.output(); //打印局部变量
这里的this也是执行调用output函数的对象outputagain,所以this指向outputagain的variable属性。
对于上面两个例子,我们已经知道this是由函数的执行环境来决定的。所以,有的时候我们需要改变当前的执行环境的指向,我们就需要用到apply、call、bind
例如:
var obj = {
a:"obj的a"
};
var a = "window的a";
function outputtest() {
console.log(this.a)
}
outputtest() //打印 window的a
outputtest.apply(obj) //打印 obj的a
可以理解为apply改变了outputtest函数执行时this的指向。所以,这里的this是指向obj的。
关于apply、call两个都是直接将方法执行掉。不同的是参数不同
apply(参数1,arguments) 参数1--新this对象 、参数2--数组
call(参数1,args1,args2.....) 参数1 -- 新this对象 、参数2 -- 参数列表
参数1为空时。默认为指向window。 例如 outputtest.apply(null) 或者 outputtest.apply() //打印 window的a
严格模式为undefined;
bind本身是"绑定"的意思。
例如: var variable = "全局边量";
var obj2= {
variable: "局部变量",
output: function(){
console.log(this.variable )
}
}
obj2.output(); //打印 局部变量
var outputtest1 = obj2.output;
outputtest1(); //打印 全局变量
var outputtest2 = obj2.output.bind(obj2);
outputtest2(); //打印 局部变量
从例子中可以理解为outputtest2绑定在了obj2所以执行的时候打印局部变量。
bind(参数1,arg1,arg2,...) 参数1 -- 新this对象 参数2 -- 参数列表
不同的是bind绑定后并不立即执行。而是需要再次将方法执行。