使用this对象

Author:Helene

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。转载请注明来自Helene的博客

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中新式箭头指向