关于javascript里面的this对象,有时候会有一些迷糊,下面用一些例子来分析一下:
var name ="window";
function fun (){
return this.name;
}
alert(fun());//window
var name ="window";
function fun (){
name = "function";
return this.name;
}
alert(fun()); //function
由上面两个例子可以看出,fun()函数里面返回的this.name的值是在作用域链中查找,这个不难理解。下面我们继续看下面一个例子:
var name ="window";
var fun = {
name : "function",
getNameFun : function(){
return this.name;
}
};
alert(fun.getNameFun()); //function
var aa = fun.getNameFun;
alert(aa());//window
上面的例子中,用不同的方法来实现对fun()函数内部的getNameFun方法的调用,而得出了两个不同的结果。从上面的例子中我们引出一个概念,即this是是指向调用它的对象。fun.getNameFun()的写法中,this指向的是fun对象,所以结果为"function";在第二种写法中,aa()等价于window.aa(),所以this指向的是全局环境Global,结果即为“window”。
this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数作为某个对象的方法调用时,this等于那个对象。即this是是指向调用它的对象。
在闭包中使用this对象可能会导致一些问题,下面我们来分析一下下面的例子:
var name ="window";
var fun = {
name : "function",
getNameFun : function(){
return function(){
return this.name;
}
}
};
alert(fun.getNameFun()()); //window
var aa = fun.getNameFun();
alert(aa());//window
在上面例子中我们可以看出,我们想让闭包里面的this.name返回的是“function”,但是执行结果不如人意,返回的是“window”,说明在这代码中,this指向的是全局对象Global,而不是指向外部函数中的对象(匿名函数的this对象通常指向window)。fun.getName()()和var aa = fun.getNameFun();aa();表达的意思是一样的,aa()等价于window.aa(),则this指向的是Global对象。因为每个函数在被调用的时候都会自动去的两个特殊变量:this和arguments,内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此比可能直接反问外部函数中的这两个变量。下面有这个方法方法可以让闭包直接访问fun对象。
把外部作用域的对象保存在闭包能够访问到的变量里
var name ="window";
var fun = {
name : "function",
getNameFun : function(){
var that = this;
return function(){
return that.name;
}
}
};
alert(fun.getNameFun()()); //function
在上面代码中,在定义匿名函数之前,我们把this对象赋值给了一个名字叫做that的变量。而在定义了闭包之后,闭包也可以访问这个变量,因为它是我们在包含函数中特意声明的一个变量,因此函数返回之后,that也依然引用着fun,所以执行结果为“function”。
在这里扩展一下,像上面例子中,强行将this绑定给其他指定对象,js中改变this的指向还有其他的一些方法:
方法一:call、apply和bind方法
方法二: new 方法
方法三:ES6中新式箭头指向