JavaScript this 关键字
本文最后更新于 2024年6月7日 下午
我接触过Python这门语言,Python中也是用
this
关键字实现了面向对象的某些概念。JavaScript中也有异曲同工之妙,所以见到this
时我并不是很陌生,但是没想到JavaScript中的this
的注意事项却比Python中的多得多,而且很让人头大。JavaScript真是一门混乱的语言! 🥱
属性
指向对象
简单来说:this
用来指代属性或方法当前所在的对象。
1 |
|
有的语境下this
可能不指代任何对象,如下函数中出现this
关键字,但是在这个函数未被调用的情况下,this
不指代任何对象。
1 |
|
这时候JavaScript
中的this
游离于对象之外,任意一个函数的定义中的都可能出现this
关键字。this
指向的对象取决于他调用的对象,例如:
1 |
|
describe
本为在对象A
中定义的方法,将B
对象的describe
方法也指向内存中的相同位置,但因为调用其的对象不同,导致结果的不同。换句话也可以理解为他所处的环境(上下文),而环境的判断方式为——寻找this
关键字的左邻最近对象。例如:
1 |
|
再看一个稍复杂的例子:
1 |
|
指向window
距离包含this
的函数m
的最左临近对象为b
,所以this
所指的对象为b
,b
中不存在属性p
,所以输出undefined
。
但是也会出现不存在最左临近对象的情况,这时候this
所指的就是顶层对象window
。
1 |
|
这时候可以采用“严格模式”,“严格模式”下函数中的this
不允许被指为window
,不然则会报错。
1 |
|
使用场合
-
全局环境
1
2
3
4
5
6this === window // true
function f() {
console.log(this === window);
}
f() // true -
构造函数
1
2
3var Obj = function (p) {
this.p = p;
}; -
对象中方法
1
2
3
4
5
6var obj ={
foo: function () {
console.log(this);
}
};
obj.foo() // obj
注意
多层嵌套下的this
下面的例子有些复杂,我想了一会。
1 |
|
可以对其进行如下的变体:
1 |
|
可以发现f2
被声明定义之后调用,调用时它不存在最左临近对象,因此调用它的是window
。
换一种思路,f2
被调用的情况不属于构造函数
也不属于对象的方法
,因此一定是全局环境。两种方法得出的结论是一致的。
数组中的this
与上面同理,调用其的是window
,不展开说了。
1 |
|
回调函数中的this
1 |
|
此时调用函数的对象为DOM
元素,也即this
的指向对象。
绑定this的方法
call()
函数实例的call
方法,可以指定函数内部this
的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。
call
方法的参数,应该是一个对象。如果参数为空、null
和undefined
,则默认传入全局对象。
1 |
|
如果call
方法的参数是一个原始值,那么这个原始值会自动转成对应的包装对象,然后传入call
方法。
1 |
|
call
方法还可以接受多个参数。call
的第一个参数就是this
所要指向的那个对象,后面的参数则是函数调用时所需的参数。
1 |
|
apply()
apply
方法的作用与call
方法类似。唯一的区别就是,它接收一个数组作为函数执行时的参数,使用格式如下:
1 |
|
bind()
bind()
方法用于将函数体内的this
绑定到某个对象,然后返回一个新函数。
1 |
|
bind()
也可以接收多个参数,这些参数将会绑定原函数的参数。
注意&用法
-
bind
每次运行就返回一个新函数,所以下面的用法是无效的。1
2element.addEventListener('click', o.m.bind(o));
element.removeEventListener('click', o.m.bind(o)); -
与回调函数结合,解决
this
指向的问题。1
2
3
4
5
6
7
8
9
10
11
12
13
14var counter = {
count: 0,
inc: function () {
'use strict';
this.count++;
}
};
function callIt(callback) {
callback();
}
callIt(counter.inc.bind(counter));
counter.count // 1若不这样做,
callback
调用时的this
指向即为window
。