思维扭曲暗示了这一点.var访问

Mind twisting implied this.var access

本文关键字:这一点 var 访问 暗示      更新时间:2023-09-26
x = {}
function f1 () {
    this.v1 = 'cool'
    try { console.log('v1:', v1) } catch(e){ console.log('error') }
}
f1.bind(x)()
f1()
f1.bind(x)()
f1()
输出:

error
v1: cool
v1: cool
v1: cool

请解释为什么这段代码只打印一次error,然后再打印cool

为什么v1没有this就能工作?

第二次调用没有bind()f1()(其中this隐式地是window),将全局变量v1(或window.v1)赋值给'cool',这是随后打印的值。

有趣的问题

为什么不用这个关键字就可以使用v1 ?

因为你的"this"关键字将被绑定到"window"对象,这是特殊的。在window的情况下,变量对象与它的this对象/上下文相同。

简单地说,窗口对象上的变量和属性是一回事。

下面是ECMA-262的一个例子。

var a = new String('test');
alert(a); // directly, is found in VO(globalContext): "test"
alert(window['a']); // indirectly via global === VO(globalContext): "test"
alert(a === this.a); // true
var aKey = 'a';
alert(window[aKey]); // indirectly, with dynamic property name: "test"

首先,您记录的不是this.v1,而是v1。这是对v1全局变量的引用,该变量应该在window上定义。每次你记录的不是x.v1,而是window.v1

this在没有限定作用域的函数中引用全局window。所以当你第一次调用它时,v1是在x上创建的,但是当你第二次调用它时,它是在window上创建的。