绑定范围 JavaScript



我试图弄清楚使用绑定的范围。我对boundF1的输出感到困惑.这是怎么回事?

// console.log(x) ReferenceError: x is not defined
// setting this.x - this here is global or window
this.x = 5;
console.log(x) // 5
function f1() {
console.log(x); // 5
console.log(this.x); // 5
}
// Lexically bound this to window 
f2 = () => {
console.log(x); // 5
console.log(this.x); // 5
}
f1()
f2()
boundF1 = f1.bind({x:1});
boundF2 = f2.bind({x:1});

boundF1() // 5 1 Why is this not 1, 1. How is x resolved here? Does it check local vars, then global vars. Would it ever use this? What is the scoping rule?
boundF2() // 5 5

原因x将始终在作用域中查找变量。它与this(上下文(无关。当你调用.bind时,你只在函数内部设置this的值。

当你引用一个独立变量时,如console.log(x),解释器将尝试在外部作用域的某个地方找到一个同名的独立变量。在这里,外部作用域最终会到达全局作用域,因此console.log(x)解析为console.log(window.x)

this的属性不会被添加到函数的变量环境中;要引用this的属性,你必须显式地这样做,例如:

console.log(this.x);

并不是说你应该使用它,但有with,它允许您引用对象的属性,就好像它们是独立的变量一样(这听起来像您认为的事情会自动发生(,但强烈建议不要这样做(并且在严格模式下禁止(。

this.x = 5;
function f1() {
with (this) {
console.log(x); // 5
console.log(this.x); // 5
}
}
boundF1 = f1.bind({x:1});
boundF1()

在 f2 中,因为它是一个不可绑定的箭头函数,xthis.x都指window.x

在 f1 中,x将首先尝试查找任何局部范围的变量 x,如果不能,则将在全局范围内搜索x。但是因为它是绑定的,所以this不再指window而是你绑定到的对象,所以this.x是你绑定到的对象的 x 值。

在第一个 print 语句中f1()的函数中,您打印x而不是this.x,因此当您将其与对象{x:1}Function.prototype.bind()绑定时,您将this作为对象传递{x:1}。 但是在函数中,您是从全局范围读取x的值,而不是从绑定到的this上下文中读取的值。

因此,当您执行函数f1并打印x时,它首先在本地范围内查找x,因为它没有找到任何它将在父范围(在这种情况下是全局范围(中查找的内容。

如果在全局范围内没有声明x,您将获得ReferenceError

function f1() {
console.log(this.x); // 1
console.log(x); // ReferenceError as x is not declared in any scope
}
f1.bind({x:1})();

范围规则在 MDN 文档中进行了解释:

作用域

也可以在层次结构中分层,以便子作用域具有 访问父范围,反之则不然。

最新更新