Javascript函数中的this

与面向对象中的 this 不同,要判断javascript函数中的 this 到底指向何方,需要知晓一些规则,然后根据具体的执行场景去判断。

this 到底指向那里?

先来看一个经典的例子:

1
2
3
4
5
6
7
8
9
10
11
12
function getName() {
console.log(this.name)
}

var stu = {
name: "tom",
getName: getName
}

console.log(stu.getName())

setTimeout(stu.getName, 100)

把以上的代码放入一段 HTML 中,例如:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<body>
Please see the console.
</body>
<script type="text/javascript">
// javascript
</script>
</html>

就可以看到结果。

确定 this 的规则

首先,找到函数的直接调用位置,然后根据以下规则来顺序判断:

  1. 在由 new 创建的新对象中,绑定到新创建的对象。
  2. 由call或者apply(或者bind)调用,绑定到指定的对象。
  3. 由上下文对象调用,绑定到那个上下文对象。
  4. 默认:在严格模式下绑定到undefined,否则绑定到全局对象。

下面我们来解释一下每条规则

在由 new 创建的新对象中

看下面的代码:

1
2
3
4
5
6
7
8
9
10
function foo(v) {
this.a = v
console.log(this.a)
}

var bar = new foo(2)

var a = 100

console.log(bar.a)

显式绑定中

通过执行call或者apply(或者bind)调用,绑定到指定的对象。

观察以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
function foo() {
console.log(this.a)
}

var obj = {
a: 42,
}

var a = 2

var other = function() {
foo.call(obj)
}

由上下文对象调用决定(隐式绑定)

观察以下代码:

1
2
3
4
5
6
7
8
9
10
11
function foo() {
console.log('foo')
console.log(this.a)
}

var obj = {
a: 42,
foo:foo
}

obj.foo()

默认行为

观察下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// "use strict"
function baz() {
console.log('baz')
bar()
}

function bar() {
console.log('bar')
foo()
}

function foo() {
console.log('foo')
console.log(this.a)
}

var a = 2

baz()
foo()

本文标题:Javascript函数中的this

文章作者:Morning Star

发布时间:2019年11月07日 - 19:11

最后更新:2021年04月16日 - 15:04

原始链接:https://www.mls-tech.info/web/javascript/javascript-about-this/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。