神奇的 this
JS 中有一个类似《X 战警》中变形女角色的存在this
。它的值不是固定的,随时都在发生变化。
本文的所有案例都是在浏览器环境下执行的
函数外的 this
在函数外使用 this
时,this
指向全局变量window
,也就是说var name = 'lily
和window.name = 'lily'
以及this.name = 'lily
的结果其实是相同的。
1
2
3
4
5
6
7
8
9
10
11
|
<script>
console.log("this === window", this === window);
var name = "lily";
console.log("name: ", name);
window.name = "zhangsan";
console.log("name: ", name);
this.name = "lisi";
console.log("name: ", name);
</script>
|
代码案例

函数内的 this
函数内的 this,要分为两种情况
直接调用函数
直接调用函数时函数内的 this
指向 window
对象
1
2
3
4
5
6
|
<script>
function add() {
console.log("this == window", this == window);
}
add();
</script>
|
代码案例

被其他对象调用
被其他对象调用时,函数内的this
和调用函数的对象有关:
1
2
3
4
5
6
7
8
9
10
|
<script>
var p1 = {
name: "zhangsan",
run: function() {
console.log("this.name:", this.name);
console.log("this == p1", this === p1);
},
};
p1.run();
</script>
|
代码案例

再看一个案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<script>
var p1 = {
name: "zhangsan",
run: function() {
console.log("this.name:", this.name);
console.log("this == p1", this === p1);
console.log("this == p2", this === p2);
},
};
var p2 = {
name: "lisi",
run: p1.run,
};
p2.run();
</script>
|
代码案例

在这个案例中,p1.run
的值被重复赋值给p2.run
属性。p2
是run()
方法的实际调用者,所以run()
方法中的this
指向的是p2
再来看一个:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<script>
var name = "zhangsan";
var p1 = {
name: "lisi",
run: function(a) {
console.log("this.name:", this.name);
},
};
p1.run();
var foo = p1.run;
foo();
</script>
|
代码案例

上面这个案例中,第一次的run
方法是被p1
调用的,所以函数中的 this 指向了调用者p1
;那么p1.name
的值就是lisi
;
第二次run
的属性值被赋值给了一个单独的变量foo
。foo()
实际上是直接调用了函数,它没有调用者,所以this
指向了window
对象。window.name
的值是zhangsan
再来一个:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script>
function foo() {
console.log("this.a", this.a);
}
function active(fn) {
fn(); // 没有调用者
}
var a = 20;
var obj = {
a: 10,
getA: foo,
};
active(obj.getA);
</script>
|
代码案例

这个案例中foo
函数被赋值给了obj.getA
属性,又被作为参数传递给active
函数,在active
中调用的时候,实际上还是直接执行的,没有调用者,所以函数中的this
还是指向了window
,所以window.a
的值是20
数组中的函数
1
2
3
4
5
6
7
8
9
10
11
12
|
<script>
function foo() {}
var arr = [
10,
function() {
console.log("this == window", this == window);
console.log("this == arr", this == arr);
console.log("this[0]=", this[0]);
},
];
arr[1]();
</script>
|
代码案例

上面案例中,数组中的函数执行的时候,实际上是被数组调用的,也就是说数组是函数的实际调用者,所以函数中的this
指向了调用者arr
本身。