什么是this?

定义:调用函数时,call后面的第一个值

如何找到this?

由定义可知,this就是call后面的第一个值,只要确定了call后面的值,即可找到this。换句话说,只需要把函数调用改成带有call的调用即可

函数调用

JS(ES5)里面有三种函数调用形式:

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

一般,初学者都知道前两种形式,而且认为前两种形式「优于」第三种形式。

从看到这篇文章起,你一定要记住,第三种调用形式,才是正常调用形式:

1
func.call(context, p1, p2)

其他两种都是语法糖,可以等价地变为 call 形式:

1
2
3
4
5
func(p1, p2) 等价于
func.call(undefined, p1, p2)

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

请记下来。(我们称此代码为「转换代码」,方便下文引用)

至此我们的函数调用只有一种形式:

1
func.call(context, p1, p2)

举个例子吧

1
2
3
4
5
6
7
8
9
var obj = {
foo: function () {
console.log(this)
}
}

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

可以理解为

1
2
3
4
5
6
7
8
9
10
11
obj.foo()
//等价于
obj.foo.call(obj)
//因此this是obj

bar()
//等价于
bar.call(undefined)
//因此this是window

//当传入的上下文是null或undefined时,浏览器默认this就是window,严格状态下是undefined

箭头函数

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

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

贴两个精髓文章

一文搞懂 this、apply、call、bind

关于this的理解