0

我试图弄清楚使用绑定的范围。我对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

4

4 回答 4

2

Cause将始终在范围内x查找变量。它与(上下文)无关。当您调用 时,您只需设置函数内部的值。this.bindthis

于 2019-08-30T10:34:50.297 回答
1

在 f2 中,因为它是一个不可绑定的箭头函数,x并且this.x都引用window.x.

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

于 2019-08-30T10:35:16.553 回答
1

当您引用独立变量时,如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()

于 2019-08-30T10:35:18.180 回答
0

f1()在第一个 print 语句的函数中,您打印的是xnot this.x,因此当您将其与对象绑定时,{x:1}Function.prototype.bind()将传递thisas{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 文档中进行了解释:

范围也可以分层分层,以便子范围可以访问父范围,反之则不行。

于 2019-08-30T10:36:29.360 回答