【问题标题】:ES6 arrow function and lexical scope inside a function [duplicate]ES6箭头函数和函数内的词法范围[重复]
【发布时间】:2018-07-02 20:37:08
【问题描述】:
let a = () => (
  {
    name:"Anna",
    func: () => console.log(this.name)
  }
)

let b = () => (
  {
    name:"Brian",
    func: function(){ console.log(this.name) }
  }
)

let c = function(){
  return(
    {
      name:"Charlie",
      func: function(){ console.log(this.name) }
    }
  )
}

let d = function(){
  return(
    {
      name:"Denny",
      func: () => console.log(this.name)
    }
  )
}

这 4 个函数具有混合和匹配的函数语法。调用嵌套函数时,func:with箭头函数返回空白。

a().func() // returns blank
b().func() // returns "Brian"
c().func() // returns "Charlie"
d().func() // returns blank

我以为箭头函数保留了“this”的范围?这种行为似乎与我的想法相反。箭头函数何时超出范围?

【问题讨论】:

  • this 有帮助吗?
  • 如果你不是 console.log(this.name); 你是 console.log(this, this.name) - 那么你会看到 this 实际上是什么,而对于 @987654331 @ 和 d 理解为什么输出是 blank 而不是 undefined 即因为 window.name 是一个东西
  • 我打算把它编辑成一个可运行的 sn-p,但显然this.name 在编辑器中返回了一个guid,并不能真正证明这一点.....跨度>

标签: javascript ecmascript-6


【解决方案1】:

对于 A 案例,您实际上是在将其一直保留到 window(如果在浏览器中运行),因此您要返回的是 window.name。

然而,至于 D,它仍然返回空白,因为它在返回的“this”的函数级别上。在您的情况下,由于您没有创建 D 的新实例,而是将 d 用作功能对象本身,因此 this 也指向 window.d 。 (稍后我会发布更多关于后者的信息,但现在,这里是一个示例)。

let e = function(){
  this.name = "Elizabeth2"  //this is on the functional level
  return(
    {
      name:"Elizabeth1",
      func: () => console.log(this.name)
    }
  )
}
e().func();       // Elizabeth2 
                  // even though it is on the functional level, the way you're calling it here makes this.name == window.name;
let ee = new e(); // however, imagine if you did this kind of a call instead
ee.func();        // Elizabeth2
                  // this is also on the functional level, HOWEVER, it is not binding this.name to window.name
ee.name;          // Elizabeth1
e().name;         // Elizabeth1
e()['name'];      // Elizabeth1
e();              // {name: "Elizabeth1", func: ƒ}

如果 func 绑定到匿名函数而不是匿名箭头函数,现在显示差异。

e = function(){
  this.name = "Elizabeth2"
  return(
    {
      name:"Elizabeth1",
      func: function(){console.log(this.name)}
    }
  )
}
e().func();  // Elizabeth1
e().name;    // Elizabeth1
e()['name']; // Elizabeth1
e();         // {name: "Elizabeth1", func: ƒ}

【讨论】:

  • 谢谢!箭头函数“this”和普通函数“this”指向不同的层......有趣......
  • 在上述情况下,“层”实际上是窗口。如果要存在 e 的新实例,它只会在功能层上,例如 let echild = new e(); echild.func()
  • 我还添加了这里的新关键字如何也可以改变处理方式背后的行为。
【解决方案2】:

当您定义ad 时,this 的值是顶级window 对象,因为您不在某个其他对象的上下文中,这将保存在箭头中职能。 window.name 是一个空字符串,所以当您调用 a.func()d.func() 时会看到它。

箭头函数通常不应该用作方法函数,因为它们无法访问被调用的对象。当您想从创建它们的位置保留 this 的绑定时使用它们(就像其他闭包变量一样)。

【讨论】:

  • 如何更改 a 和 d 以使它们返回“Anna”和“Denny”?
  • 我不认为你可以。如果需要,请不要使用箭头函数。
  • @GundamMeister - 换句话说,为工作使用正确的工具 - 在 MDN 文档中,它声明 这些函数表达式最适合非方法函数 - 你的代码正在尝试将它们用作方法函数
猜你喜欢
  • 2016-03-25
  • 2018-08-02
  • 2018-07-18
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-08
  • 2015-03-17
相关资源
最近更新 更多