JavaScript:this指针

  • JavaScript:this指针已关闭评论
  • 106 次浏览
  • A+
所属分类:Web前端
摘要

this指针,存储的是一个内存地址,如同变量一样,指向一块内存区域;而这个内存区域,保存的就是一个对象的数据,那么这个对象是什么呢?

this指针,存储的是一个内存地址,如同变量一样,指向一块内存区域;

而这个内存区域,保存的就是一个对象的数据,那么这个对象是什么呢?

通常来说,this指针,主要是用在方法(函数)中,用来指向调用方法(函数)的对象;

比如说,有个方法eat(),这个方法里面有个this指针;

Tom调用eat时,this指针指向的就是"Tom";

Jerry调用eat时,this指针指向的就是"Jerry";

也就是说,this指针,总是指向直接调用者。

好,现在我们来看一下,两个不同于上面所述规则的特殊情况:

  • ”没有“调用者

    看下面代码:

    JavaScript:this指针

    我们知道,如果是使用var声明的变量,实际上是成为了window对象的方法,那么aaa()实际上就是window.aaa(),也就是省略了window的写法,那么,this指向的就是window对象,我们可以理解;

    但是,上面我们使用let声明的变量,为什么this指向的还是window对象呢?

    要知道,let声明的函数,并不是window对象的方法,window对象也无法调用,那么此时aaa()是由谁调用的呢?我们现在无法得知,但是可以肯定的是,绝对不是window对象;

    再来看函数aab(),虽然它是function声明的函数,但是因为它是在代码块中声明的,所以它也不是window对象的方法,那么aab()又是被谁调用的呢?为什么它的this指针,也指向window对象呢?

    事实上,这是历史遗留问题,如果我们开启了严格模式,此时两个this将都会是undefined,这是符合逻辑的,既然“没有”调用者,那么this就没有指向,当然就是undefined

    如下所示,就印证了我们前面所说的:

    JavaScript:this指针

  • 箭头函数没有this指针

    首先说明,箭头函数,确实没有自己的this指针;

    也就是说,箭头函数里面的this,并不能指向调用箭头函数的对象;

    那么,此时this,指向的是谁呢?

    看下面代码:

    JavaScript:this指针

    我们将上图与上上图进行比较,仔细观察一下输出结果的不同;

    在严格模式下,上图三个this指向的都是window对象,与上上图完全不一样,这至少说明,箭头函数的this,和function声明的函数的this,有不同的表现;

    再看下面这个代码:

    JavaScript:this指针

    上图与上上图的区别,就是在最后一行代码,我们将obj1作为obj2的一个对象,从而再多一次调用arrow()方法,结果依然还是指向window对象,似乎无论增加多少次中间调用者,最终都会指向window对象,说明箭头函数的this,并不是在指向调用箭头函数的对象;

    现在我们尝试,将箭头函数arrow的可见性,降低一些,看下面的代码:

    JavaScript:this指针

    上图将箭头函数内arrow的可见性,控制在了用关键字function声明的函数外arrow内部,这样,要使用箭头函数,就得调用外arrow

    对于arrow(),上面我们已经讨论过,此时外arrow函数“没有”调用者,所以this是undefined

    对于obj1.arrow(),此时this指向,调用外arrow函数的obj1;

    对于obj2.arrow(),此时this指向,调用外arrow函数的obj2;

    对于obj2.obj1.arrow(),此时this指向,调用外arrow函数的obj1,注意,此时obj2调用obj1,而obj1调用外arrow函数,所以this指向obj1;

    可以看到,this的表现,完全就是外arrow函数的this指针的表现;

    也就是说,此时,箭头函数的this,其实并不属于箭头函数,而是属于包围箭头函数的外部代码块,在这里也就是指外arrow函数;

    所以,在考虑箭头函数的this指针的指向的时候,我们完全可以把箭头函数当成一般的执行语句,而不是一个函数,这也是为什么说箭头函数没有this指针的缘故;

    现在回过头看上上图,我们就能理解,此时箭头函数是直接在script标签中的,作为一个普通的执行语句,它的外层只剩下浏览器窗口,也就是window对象了,所以这些this指针才全部指向window对象;

总结:

  • this指针,总是指向它所在函数体的直接调用者;
  • 直接函数名()这样“没有”调用者的函数调用,在严格模式下,this为undefined;在普通模式下,this指向window对象;
  • 箭头函数没有this指针,此时将箭头函数当做一般语句,this指针属于箭头函数所在的函数体的直接调用者;而且注意,如果箭头函数是全局作用域的话,无论什么模式,this总是指向window对象;