在JavaScript当中我们常常因为this的指向问题搞得焦头烂额,不仅会想,为什么this是这种设计,为什么会有this。这实际上和JavaScript的内存设计有关。
1,对象在内存中的结构。
var obj = { name : '张三' };
上面的代码将一个对象赋值给变量obj。JavaScript 引擎会先在内存里面,生成一个对象{ name: ‘张三’ },然后把这个对象的内存地址赋值给变量obj。
在内存中实际上是这样保存的。
我们知道JavaScript对象的属性都有一个属性描述对象。
跟上面一样name也是个地址,而实际的值存在value当中。
2,函数在内存中的结构。
var a = function () {}
函数和对象差不多,先生成个函数,把函数的地址复制给变量a,类似于这样,
那现在就出现一种情况。
如果上面obj的name属性是个函数,它应该是什么样的呢。
var obj = { name: function () {} };
我们知道name实际的值储存在value当中,当是个方法时,他储存的就是这个方法的地址,而不是实际的函数体。
由于函数是一个单独的值,所以JavaScript中的函数可以单独运行
var f = function () {};var obj = { f: f };// 单独执行f()// obj 环境执行obj.f()
JavaScript 允许在函数体内部,引用当前环境的其他变量。就是访问其作用域的变量。
需要一种机制,当前函数要知道自己到底是在什么环境下执行。this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。
函数自己并不知道谁调用了它, 就像上面所说的究竟是obj.f调用的,还是全局调用的。this关键字就代表了调用时的环境。
var f = function () { console.log(this.x);}var x = 1;var obj = { f: f, x: 2,};// 单独执行f() // 1// obj 环境执行obj.f() // 2
虚线内就是函数运行环境,就是this。
(本文主要摘自阮一峰 JavaScript 的 this 原理)