this的指向
在ES5中,this总是指向最后一个调用它的那个对象,也就是说this的指向可能会发生变化。
在ES6中,箭头函数的this指向其被定义时所在的对象。
看看以下的几个例子:
var name="windowName";
function func(){
var name="funcName";
console.log(this.name);
}
func(); //打印"windowName",因为调用func()的对象是全局对象window
console.log(this.name); //打印“windowName”,this指向的对象是全局对象window
var name="windowName";
var obj={
name:"objName",
func:function(){
console.log(this.name);
}
}
obj.func(); //打印“objName”,因为调用func()的对象是obj,this指向obj
var name="windowName";
var obj={
name:"objName",
func:function(){
console.log(this.name);
}
}
window.obj.func(); //打印"objName",因为最终调用func()的对象依然是obj,this指向obj
var name="windowName";
var obj={
func:function(){
console.log(this.name);
}
}
window.obj.func(); //打印undefined,因为最终调用func()的对象是obj,但是obj内部并没有对name的定义
var name="windowName";
var obj={
name:"objName",
func:function(){
console.log(this.name);
}
}
var f=obj.func;
f(); //打印“windowName”,虽然将obj对象的func方法赋值给了变量f,但f并没有调用,func函数最后还是被window调用,this指向window
var name="windowName";
function func(){
var name="funcName";
inner();
function inner(){
console.log(this.name);
}
}
func(); //打印"windowName",因为调用func的对象时window,此时this指向window
call,apply,bind
call(),apply(),bind()都可以改变this指向。
apply()方法调用一个函数,其具有一个指定的this值,以及作为一个数组(或类数组对象)提供的参数。
apply语法:func.apply(thisArg, [argsArray])
call()方法与apply()作用一致,区别是传入的参数 不同。
call语法:func.call(thisArg, arg1,arg2,...)
bind()方法创建一个新的函数,称为绑定函数,需要手动调用。
var obj={
name:"objName",
func:function(a,b){
console.log(a+b);
}
}
var f=obj.func;
f.call(obj,1,2); //打印3
var obj={
name:"objName",
func:function(a,b){
console.log(a+b);
}
}
var f=obj.func;
f.apply(obj,[1,2]); //打印3
var obj={
name:"objName",
func:function(a,b){
console.log(a+b);
}
}
var f=obj.func;
f.bind(obj,1,2); //没有输出
var obj={
name:"objName",
func:function(a,b){
console.log(a+b);
}
}
var f=obj.func;
f.bind(obj,1,2)(); //输出3
call vs apply
相同点:
(1)call和apply都是为了改变某个函数运行时的上下文而存在的,换句话说就是为了改变函数体内部this的指向。
(2)当一个对象没有某个方法而另一个对象有时,就可以借助call或apply来实现这个方法。
区别:
(1)接受参数的方式不一样。call需要把参数按顺序传递进去,而apply则是把参数放在数组中传递进去。
(2)当参数数量不确定时,推荐使用apply,例如获取函数的参数arguments。
call,apply vs bind
相同点:
(1)三者都用来改变函数的this对象的指向
(2)三者的第一个参数都是this要指向的对象,也就是指定的上下文
(3)三者都可以利用后续参数传参
区别:
apply/call会立即执行函数,bind()是返回对应函数,需要手动调用,只有在调用时才会执行。
当你希望改变上下文环境后并非立即执行,而是回调执行的时候,使用bind(),反之使用call/apply。