this原理
# 问题的由来
let obj = { foo: function () {} }; let foo = obj.foo; // 写法一 obj.foo(); // 写法二 foo();
1
2
3
4
5
6
7
8
9
10
在此代码中,虽然obj.foo
和foo
指向同一个函数,但是执行结果可能不一样:
let obj = {
foo: function () {
console.log(this.bar)
},
bar: 1
};
let foo = obj.foo;
let bar = 2;
obj.foo(); // 1
foo(); // 2
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
这种差异的原因,就在于函数体内部调用了this
关键字。
很多教科书会告诉你,this
指的是函数运行时所在的环境, 对于obj.foo
来说,foo
运行在obj
环境,所以this
指向obj
;
对于foo()
来说,foo
运行在全局环境,所以this
指向全局环境。
所以,两者的运行结果不一样。
但是,为什么会这样?为什么obj.foo
就是在obj
环境执行,而一旦let foo = obj.foo
,foo()
就变成全局环境执行?
# 内存的数据结构
JavaScript
之所以有this
的设计,跟内存里面的数据结构有关系。
let obj = { foo: 5 };
1
此代码将一个对象赋值给obj
,JavaScript
引擎会先在内存里面,生成一个对象{ foo: 5 }
,然后把这个对象的内存地址赋值给变量obj
。
也就是说,变量obj
是一个地址。后面要读取obj.foo
,引擎先从obj
拿到内存地址,然后再从该地址读出原始的对象,返回它的foo
属性。
或者说,当前函数体内的this
,谁调用了就指向谁
编辑 (opens new window)
上次更新: 2021/08/22, 01:09:59