共计 711 个字符,预计需要花费 2 分钟才能阅读完成。
JavaScript 函数是一个单独的值,它可以在不同的环境(上下文)中执行,同时 JavaScript 允许在函数体内部,引用当前环境的其他变量。
为了能够在函数体内部获得当前的运行环境(context)。所以,this 就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。
在 JavaScript 语言中,this 的设计跟内存的数据结构有关。基本数据类型是按值访问的,引用类型存储在内存中。
比如:
var outer={
fn:function(){console.log(this.x)},
x:2
}
var x=1;
var runFn=outer.fn;
outer.fn() //2
runFn() //1
上面的代码中,将一个对象赋值给变量 outer,JavaScript 引擎会先在内存中生成对象 {fu:function(){},x:2},然后把对象的内存地址赋值给变量 outer。
也就是说,变量 outer 保存的是一个地址。后面如果要读取 outer.fn,引擎先从 outer 拿到内存地址,然后再从该地址读出原始的对象。
然后原始对象根据 fn 属性值,然而 fn 的属性值是一个函数,这时 JavaScript 引擎将函数单独保存在内存中,然后将函数的内存地址赋值给 fn 属性的 value 属性。
然后获取函数的地址内存地址,outer.fn() 函数运行后,其函数内部上下文(context)指向的就是原始对象环境,即 his 指向 outer, 返回 outer 的 x 属性值。
outer.fn() 是通过 outer 找到 fn,所以就是在 outer 环境执行。一旦 var runFn = outer.fn,变量 runFn 就直接指向函数本身,所以 runFn() 就变成在全局环境执行。