前几天,阮大大在其博客文章上更新了一篇文章(JavaScript 的 this 原理),通俗易懂地介绍了this的原理。

在这篇文章介绍之前,我们在教科书或者网上看到介绍this的文章都会是类似下面的这种定义:this指向函数调用时所处的环境对象,即取决于运行时产生的执行上下文,所以就会区分函数的几种不同执行情况:

  • 作为构造函数执行 this -> 构造实例
  • 作为对象属性执行 this -> 对象
  • 作为普通函数执行 this -> 函数执行所处环境
  • call、apply、bind this -> 传入参数(当不传或传入null、undefined时)

还有一些特殊情况:

  • 在浏览器中setTimeout、setInterval和匿名函数执行时,其中 this -> window(Node中global/module)

但是具体为什么是这样的,环境对象到底是什么,就理解的不是很清楚:

在阮老师的这篇文章里,首先引出内存中数据结构,以var obj = {foo: 5}为例,其在内存中结构如下图所示:

而对象本质上在内存中的存储,是对应一个属性描述对象的,如下图:

如果属性的值是原始类型,那么就直接存储在value属性中,但如果值为引用类型,那这里会继续嵌套下去,而value值保存引用类型值存储的地址。

那么,加入这个值是一个函数的话,因为函数也是引用类型,那函数会单独存储在内存中的一块区域,value属性保存的函数的地址

由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。JavaScript是允许在函数体内部,引用当前环境的其他变量,那如果能够能够在函数内部获得当前的运行环境(context)——this,其设计目的就是在函数体内部,指代函数当前的运行环境。

那运行环境具体指的是什么意思呢?就是因为函数是内存中单独的一块区域,所以通过谁访问到这个函数,那么谁就是函数执行的允许环境。

参考资料:

(本篇完)


书籍推荐