JS中this怎么判断

61 阅读2分钟

代码中的this是什么?

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

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

请解释最后两行函数的值为什么不一样?

函数调用

首先从函数调用说起。 JS(ES5)里面有三种函数调用形式:

func(p1, p2) 
obj.child.method(p1, p2)
func.call(context, p1, p2)

其中第三种方式是正常调用方式,其他两种方式都是语法糖,可以等价的变为call形式。

func(p1, p2) 等价于
func.call(undefined, p1, p2)

obj.child.method(p1, p2) 等价于
obj.child.method.call(obj.child, p1, p2)

这样,this 就好解释了

this,就是上面代码中的 context。即call的第一个参数。

当你写下面代码时

function func(){
  console.log(this)
}

func()

等价于

function func(){
  console.log(this)
}

func.call(undefined) // 可以简写为 func.call()

按理说打印出来的 this 应该就是 undefined 了吧,但是浏览器里有一条规则:

如果你传的 context 是 null 或 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)

所以上面的打印结果是 window。

再看 obj.child.method(p1, p2) 的 this 如何确定

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

obj.foo() 

等价于

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

obj.foo.call(obj) 

所以this就是obj。

再看一个

function fn (){ console.log(this) }
var arr = [fn, fn2]
arr[0]() // 这里面的 this 又是什么呢?

我们可以把 arr0 想象为arr.0( ),虽然后者的语法错了。

        arr[0]() 
假想为    arr.0()
然后转换为 arr.0.call(arr)
那么里面的 this 就是 arr 了

箭头函数

箭头函数里并没有 this,如果你在箭头函数里看到 this,你直接把它当作箭头函数外面的 this 即可。外面的 this 是什么,箭头函数里面的 this 就还是什么,因为箭头函数本身不支持 this。

有人说「箭头函数里面的 this 指向箭头函数外面的 this」,这很傻,因为箭头函数内外 this 就是同一个东西,并不存在什么指向不指向。


关于this的使用,参考链接:this 的值到底是什么?一次说清楚 - 知乎 (zhihu.com)