【问题标题】:The this keyword not working with arrow functions [duplicate]this 关键字不适用于箭头函数[重复]
【发布时间】:2019-08-06 02:38:11
【问题描述】:

我正在学习 ES6,我只是想将我的 ES5 知识转换为 ES6。

这是我的 ES5 代码:

function click() {
  this.className += ' grab';
  setTimeout(() => (this.className = 'remove'), 0);
};

这是我的 ES6 代码:

const click = () => {
  this.className += ' grab';
  setTimeout(() => (this.className = 'remove'), 0);
  console.log('RENDERING');
}

我的问题是 this.className += 'grab';setTimeout(() => (this.className = 'remove'), 0); 没有'不运行该功能。但是 console.log 会显示在日志中。

方法是否不适用于箭头函数?

【问题讨论】:

  • this 不是一种方法,并且在箭头函数内部是不同的 - 阅读 documentation 以了解区别... didn't run the function 是的,确实如此,只是你不知道是什么你还在做
  • this 关键字在箭头函数中的作用不同。 Read this section 的文档。
  • Aside - 考虑使用el.classList.add('grab')(和el.classList.remove('grab'))而不是手动操作类名字符串。 more info
  • 这表明并不是所有的函数都应该仅仅因为箭头函数很酷就被转换为箭头函数:p 箭头函数有特定的用途,只能在适当的时候使用

标签: javascript function arrow-functions


【解决方案1】:

没有足够的上下文给你一个好的答案,但有一件事很突出。箭头函数保持作用域,所以 this 内的 function click()const click 很可能不同。在 ES6 版本中,this 将引用闭包创建期间的 this,这可能不是您想要的。

Arrow Functions at MDN 清除它:

箭头函数没有自己的this.

...这意味着this 将从声明范围继承。

ES6 箭头函数不仅仅是一种声明函数的新方式,function myFunction(...) 语法本身并没有错,也不会消失。箭头函数在将函数作为参数传递时避免了一些冗长(例如,传递给forEach),并避免在某些情况下需要将函数重新绑定到不同的this。将所有函数声明转换为箭头语法并不是升级。

【讨论】:

  • @jaromanda-x 是的,您可能是对的,尤其是如果您假设该函数通常作为对象方法调用,这就是它甚至具有 className 属性的原因。耸耸肩。
【解决方案2】:

在箭头函数中,this 不是您所期望的 this。箭头函数中的this 是在您创建函数时定义的,而不是在调用它时定义的。有关更多信息,请参阅here

感谢 cmets 的 @Jaromanda X - 在这种情况下,继续使用标准函数表示法 (function() {...}) - 即仅仅因为你买了一把新螺丝刀,并不意味着旧锤子仍然不是敲钉子的最佳工具

【讨论】:

  • this 确实存在,否则 OP 会出错 - this 来自边界词法范围
  • @JaromandaX 你是对的。让我解决这个问题
  • keep using standard function notation - 也就是说,你买了一把新螺丝刀,并不意味着旧锤子仍然不是敲钉子的最佳工具
  • @JaromandaX 这实际上是一个很好的类比。你介意我把这个放在我的回答中吗?
  • 随意 - 这是我最好的之一:p
【解决方案3】:

原因是你只需要稍微重组一下。

setTimeout(() => {this.className = 'remove'}, 0)

你有括号和花括号。

您的 this 可能会或可能不会起作用,具体取决于其他代码中的结构方式

【讨论】:

  • 在这种情况下绝对没有区别——在其他情况下,区别在于箭头函数返回什么
【解决方案4】:
       const click = () => {
           console.log(this);
           this.className += ' grab';
          setTimeout(() => (this.className = 'remove'), 0);
          console.log('RENDERING');
      }
      click();
箭头函数中的

'this' 表示从哪里调用它。例如,如果我打开浏览器并转到控制台并键入上面的代码,那么“this”将成为窗口对象,因为该函数是从全局环境调用的。箭头函数也没有自己的“this”。

【讨论】:

    【解决方案5】:

    您可以为箭头函数绑定this 以访问函数和数据。您的代码应该类似于

    const click = () => {
      this.className += ' grab';
      setTimeout(() => (this.className = 'remove'), 0);
      console.log('RENDERING');
    }.bind(this)
    

    它将为箭头函数绑定this,您可以访问这些变量和函数。

    【讨论】:

    • 只有在对象中定义了this时它才会绑定
    【解决方案6】:

    箭头函数表达式是常规函数表达式的语法紧凑替代方案,尽管它没有与 this、arguments、super 或 new.target 关键字的绑定。箭头函数表达式不适合用作方法,并且它们不能用作构造函数。

    【讨论】:

      猜你喜欢
      • 2021-09-17
      • 2020-05-05
      • 2023-03-15
      • 2021-04-22
      • 2017-12-06
      • 2018-02-07
      • 1970-01-01
      • 2016-06-20
      • 1970-01-01
      相关资源
      最近更新 更多