关于JavaScript中this指向的理解

JavaScript中this的指向会随它的执行环境的改变而发生变化,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。this是在函数运行时,自动生成的一个内部对象,只能在函数内部使用。

示例1

function a(){
    var message = "hello world";
    console.log(this.message); //undefined
    console.log(this); //Window
}
a();

我们在函数a()里定义了一个变量message,并进行了打印操作,最后执行函数a()。可以发现,第一个this.message的this指向结果是undefined,第二个this指向的则是全局对象window。按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被Window对象所调用的,也就是a()相当于window.a(),下面的代码就可以证明。message是我们在函数a()内部定义的一个变量,而在全局作用域下并没有message这么一个变量,因此this.message的this所指向的全局对象window无法访问到message。

function a(){
    var message = "hello world";
    console.log(this.message); //undefined
    console.log(this); //Window
}
window.a();

同样地,如果我们在函数a()的外部定义一个message,看看是否能访问到呢?

var message = "hello world";
function a(){
    console.log(this.message); //hello world
    console.log(this); //Window
}
a();

可以看到,可以成功打印出hello world。因为此时我们定义的message是个全局变量,通过全局对象window可以访问到message。

示例2

var o = {
    message:"hello world",
    fn:function(){
        console.log(this.message);  //hello world
    }
}
o.fn();

在这里,我们首先定义了一个对象o,其包含一个属性message和一个函数fn。这里的this指向的是对象o,因为函数fn()的调用是通过o.fn()执行的,那自然指向就是对象o。因此this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁
我们知道,全局环境是最大的运行环境,每个对象都包含在全局环境当中。那么如果我们在o.fn()前面加上一个window对象会是什么结果呢?

var o = {
    message:"hello world",
    fn:function(){
        console.log(this.message);  //hello world
    }
}
window.o.fn();

可以看到,同样打印输出hello world。我们通过在浏览器中添加断点可以查看到此时的this指向的还是o对象。

示例3

var o = {
    message:"hello world",
    b:{
        message:"I'm in Shanghai",
        fn:function(){
            console.log(this.message); //I'm in Shanghai
        }
    }
}
o.b.fn();

上面的代码里,我们首先定义了一个对象o,包含一个属性message和一个对象b,在对象b里面同样也定义了一个属性message还有一个函数fn,通过o.b.fn()调用函数fn(),最终打印输出的是对象b里面的message信息。
同样地,我们再将上面的代码改写一下:

var o = {
    message:"hello world",
    b:{
        fn:function(){
            console.log(this.message); //undefined
        }
    }
}
o.b.fn();

这时,this输出的则是undefined。因为此时的this指向的是对象o,而这里的对象o里面已经没有了message属性,所以无法访问到。

至此,我们大致可以总结出几点规律:

  • 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window对象。
  • 如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
  • 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。

示例4

var o = {
     message:"hello world",
    b:{
         message:"I'm in Shanghai",
        fn:function(){
            console.log(this.message); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();

这里的this指向的却是window对象,这是为什么呢?this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,示例3中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行,所以最终指向的是window。而在示例3中,我们直接通过o.b.fn()对fn进行了执行,也就是对象b对fn()进行了调用,因此此时的this指向的是对象b。

猜你喜欢

转载自blog.csdn.net/shiyangxu/article/details/81433207