JavaScript 中的 this
我们由一段代码开始本文的主题。
1 | var obj = { |
可以看到,foo
和 obj.foo
实际上是严格相等的,它们是指向同一个代码段。由于 上下文环境 不同,所以他们运行的结果也不一样。obj.foo
的上下文环境就是 this
指向的 obj
,而 foo
的上下文环境是全局环境。
JavaScript 的内存数据结构
我们需要深入到 JavaScript 的内存数据结构去寻找答案。
1 | let obj = { foo:1 }; |
我们把一个对象 { foo:1 }
赋值给对象 obj
。这个过程实际上是 JavaScript 引擎在内存中生成一个 { foo:1 }
然后再把这个对象的内存地址赋值给 obj
。
这其实就跟 C 语言中的指针概念相似,先分配一块内存,初始化后,把内存的地址赋给一个指针。obj
起的就是一个指针的作用,它保存一个地址,JavaScript 引擎读取它时是直接从 obj
中取内存地址,然后再去改地址取原始对象。
原始对象以字典结构存储。对象的每一个属性也都对应一个属性描述对象。value
保存的是属性的值。
函数的内存结构
如果属性是一个函数,内存中的数据结构是怎样的?
1 | var obj = { bar: function () {} }; |
这个时候函数其实就是属性的值,函数在计算机中实际上就是一段代码段,它占据着一段内存。此时属性的值并不是直接保存这段代码段,而是保存它对应的内存地址,属性是指向这个函数的指针。
那么运行 bar=obj.bar
会发生什么呢?只是把 bar
这个变量也指向了 obj.bar
指向的函数所占据的内存的地址。
所以我们知道了,函数只是一个内存中存储的代码段(执行逻辑),它可以在不同的上下文 (运行环境) 中执行。
环境变量
函数如何获得上下文 (context) 呢?this
正是起这个作用。
1 | var f = function () { |
执行函数的时候会检查调用函数的指针的上下文,而函数中的 this
指代的正是这个函数指针所在的上下文。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Serendipity!
评论