JavaScript中的this到底是什么

110 阅读2分钟

相信有很多同学都不太清楚JS中的this指向的问题,下面,我将一一解释JS中的this到底是什么。

普通函数

我们看一下,下边打印出的this

var obj = {
  foo: function(){
    console.log(this)
  }
}

var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window

为什么会这样呢? 我们首先要搞清楚一点,当一个函数被调用时,它的实际调用方式是经过call方法或者apply方法加工的,例如:obj.foo(p1)函数调用,实际上是obj.foo.call(obj,p1)(其中p1为函数参数)

call方法

经过call方法调用,可以将obj.foo(p1)方法中的this指向为obj,所以,call方法第一个参数为函数的this指向,其余参数为函数的参数。

apply方法

与call方法类同,只不过第二个参数为数组,可以传递多个函数的参数值

我们再看bar(p1)方法的调用,为什么打印出的this值会是window呢?经过上述的讲解,我们的经过call方法的转换,bar(p1)函数的转换值应该为bar.call(?,p1),那么第一个参数到底是什么呢?既然我们的bar()函数打印出来的this是window,那第一个参数就应该是window,那为什么会是window呢?

当我们没有开启严格模式时,在全局调用函数时,浏览器会把call方法的第一个参数替换成window,当我们开启严格模式时,第一个参数就会是undefined,即bar.call(undefined,p1),此时。bar()函数打印出的this就不会是window。

箭头函数

我们大家都知道,在箭头函数中是没有this存在的,它的this指向指向外层作用域,那么call方法以及apply方法可以用吗?

答案是 可以的!但是,我们的call方法以及apply方法中的第一个参数(也就是指定this指向的参数)会被替换成undefined(即使指定了,也会是undefined)。

箭头函数中的 this 在定义它的时候已经决定了(执行定义它的作用域中的 this),与如何调用以及在哪里调用它无关,包括 (call, apply, bind) 等操作都无法改变它的 this。