其实,要想弄明白this的用法,只需牢记一句话:this永远指向的是调用它的对象,也就是看谁调用执行的它。
下面用几个小例子来表达演示一下
var str ='全局变量'
function a(){
var str='局部变量';
console.log(this.str); //全局变量
console.log(this) //window
}
window.a(); //函数a的console方法,由window调用
这里的this,虽然是放到函数里,但是由于调用时是用window来调用的,所以这里的this指向的就是window
var str ='全局变量'
var a={
str:'局部变量',
fn: function(){
console.log(this.str) // 局部变量
}
}
window.a.fn();
```
因为fn函数调用是由window下的a调用的,所以fu中this的指向就是a
var str ='全局变量'
var a={
str:'局部变量',
b:{
str:'局部中的局部',
fn: function(){
console.log(this.str) //局部中的局部
}
}
}
window.a.b.fn();
``
这里的fn调用,虽然是最开始也是被对象a调用的,但是window对象调用了对象a之后又调用了对象b,所以虽然上层虽然有两层对象,但是fn的this指向的是调用最近的对象,也就是说this指向的只能是它上一级的对象
var str ='全局变量'
var a={
str:'局部变量',
b:{
// str:'局部中的局部', 注释掉局部中的局部这个str,后我们看看打印出了什么
fn: function(){
console.log(this.str) //打印出了undefind
}
}
}
window.a.b.fn();
所以及时尽管对象b中没有这个str属性,但是fn中的this指向的还剩对象b,不管是否这个对象b中是否包含str
然后我们再看一下比较复杂的另一种情况
var str ='全局变量'
var a={
str:'局部变量',
b:{
str:'局部中的局部',
fn: function(){
console.log(this.str); // 全局变量
console.log(this); // window
}
}
}
var c=a.b.fn;
c();
在这里为什么打印出来的this指向的就是全局的呢?答:这里我们还是判断时候要靠一开始的那一句话,就是this永远指向的是调用它的对象,也就是看谁调用执行的它,这里在var c=a.b.fn;这一步的时候,其实是把对象b中的方法给了全局中的c,然后c就由此变成了一个拥有与fn函数一样操作的一个函数了,然后又由全局中的c调用console打印出this对象,所以这里的this指向的就是window
最后还有一种情况就是return需要注意一下,当由return返回值的时候,那么new出的对象的this,指向就可能不一样了,以下的代码例子
function fn()
{
this.user = '局部';
return {}; // 返回一个对象
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = '局部';
return function(){}; //返回一个对象
}
var a = new fn;
console.log(a.user); //undefined
function fn()
{
this.user = ‘局部';
return 1; //返回不是对象
}
var a = new fn;
console.log(a.user); //局部
function fn()
{
this.user = '局部';
return { //返回一个对象,且对象里有属性user
user:'11',
};
}
var a = new fn;
console.log(a.user); // 打印出11
为啥return的不同,this的指向就不同了呢?答:这是因为,当你return返回值是一个对象的时候,那么this了的this指向的就是返回的对象,如果返回值不是对象,那么this指向的就是还是原来new出来的函数对象
那么this的指向可以改变吗?当然可以,在js中由call,apply,bind这三个方法都是可以改变this指向的,有兴趣的可以了解一下