什么是词法“this”?

IT技术 javascript ecmascript-6
2021-03-15 03:07:35

有人可以给我简单介绍一下词法 this 吗?

“与函数表达式相比,箭头函数表达式(也称为胖箭头函数)的语法更短,并且在词法上绑定了 this 值(不绑定自己的 this、arguments、super 或 new.target)。箭头函数总是匿名的.”

这是否意味着当我使用“Fat Arrow”函数中的“this”引用调用函数成员时,“this”总是指封闭的“this”?

6个回答

您似乎对this箭头函数中发生的事情有正确的理解我将提供一个我认为有助于对话的解释,并希望能巩固您的理解。

您可能知道,当您定义一个函数并在其中使用一个变量时,它会检查该变量是否已在其作用域中定义。如果是,它会使用它!如果不是,它会检查该变量定义的封闭范围。它不断检查封闭作用域,直到找到变量或到达全局作用域。现在,不是箭头函数的函数定义this为您隐式定义因此,当您尝试this在它们的作用域中使用时,它们永远不会检查封闭作用域(因为它们在它们自己的作用域中找到它!)。箭头函数不定义它们自己的this,因此它们会转到封闭的作用域并查找它,就像它们在您尝试在其作用域中使用的任何变量一样。

如果您可以从范围中逃脱,那么它几乎不是一个封闭的范围……为什么 JS 人员不谈论线程?会更加一致。
2021-04-26 03:07:35
谢谢!阅读此答案后,它为我点击。它让我意识到在同一作用域内的变量和this定义是相互独立的。
2021-05-01 03:07:35
我不确定我们是否不同意。可能是我不清楚。关于你的最后一句话:嵌套箭头函数怎么样?
2021-05-05 03:07:35
这是错误的。变量可以在整个作用域链中找到。this在箭头函数的情况下,是“找到”的,正好在直接封闭的范围内。
2021-05-13 03:07:35

作为描述this箭头函数行为的一种方式,术语“词法this”介于混淆和错误之间。

行为很简单,this在箭头函数中是指this在周围的函数中——或者说箭头函数没有定义(或“绑定”)它自己的this.

不幸的是,“词法this这个术语可能是由于MDN 文章中关于箭头函数的措辞选择不当(直到最近还鼓励人们使用过时的术语“胖箭头函数”)。现在已经清理干净了。另请注意,规范从不使用与thisin 箭头函数相关的术语“词法” 我很想知道是谁提出了这个表达。

实际上,当前的 ECMA 2022 版本确实调用了“this”的两个可能值,用于构建函数评估上下文lexical-thisnon-lexical-this,其含义与函数“内部槽”有关[[ThisMode]],其定义指出:“lexical表示this指的this是词法封闭函数”。在第 6 版中,这在第 14.2.16 段(简而言之,关于箭头函数的评估 :) 中简单说明为“让范围成为正在运行的执行上下文的 LexicalEnvironment”。真是令人费解。
2021-05-16 03:07:35

假设您有一个点击侦听器。在该侦听器中,您正在执行一些 AJAX 操作,例如setTimeout. 到达设置时间后,将执行回调中的代码。在该回调中,您可能已经访问this以更改单击按钮的颜色。但是由于 AJAX 操作,控件将脱离上下文。ES2015 引入了箭头函数来解决这个问题。箭头函数捕获this封闭上下文值。

示例用例是:

$('.btn').click(function () {
    setTimeout(function () {
        $(this).text('new'); 
        // This will cause an error since function() defines this as the global object.
    } ,100); 
}); 

为了避免这种情况:

$('.btn').click(function () { // <- Enclosing context
    setTimeout( () => {
        $(this).text('new')  } 
        // This works, because this will be set to a value captured from the enclosing context.
      ,100);
});

写了一篇关于这个的文章,要点其中的是:不要没有想什么“这个词汇”的意思。难道担心什么“这个”箭头函数中的手段。已经知道了(或者至少,如果你不知道,那是你自己对某些外部函数作用域的混淆的错,而不是箭头函数的错)。

多年来,当您需要在某些嵌套或高阶函数中使用“this”时,您可能已经习惯于担心“this”最终意味着什么。但是有了箭头函数,你就不用担心了。您几乎肯定已经知道在您当前所处的上下文中“this”指的是什么:但是...在箭头函数中,它没有改变。因此,您可以将箭头函数视为简单的情况,将 function(){} 视为更复杂的情况。

您是否编写了一些函数并启动了一个 if(){} 块并担心“this”可能会更改为其中的内容?不?与箭头函数相同。这就是“词法这个”的意思。意思是“Hakuna matata”。

你解释它就像箭头函数总是按预期运行,而普通函数从来没有。但是this普通函数行为也很有用,例如在原型中定义方法时。
2021-04-20 03:07:35
this过去 20 年的行为是所有 JS 代码的核心,这让我感到有点奇怪,它是“复杂的”。它有什么复杂之处?如果这很复杂,那么箭头函数所做的就是通过不定义自己的this.
2021-04-27 03:07:35
箭头函数不会改变“this”的当前含义。因此,不需要像“他们在写入时绑定 this 的含义”这样的特殊的、令人困惑的新思维模型来理解他们的“this”指的是什么。它所指的内容没有改变。而已。是的,常规函数客观上更复杂。他们还有几个动态属性需要担心。他们已经存在了 20 年与这个问题无关。是的,它们仍然有用。但它们不再是完成这项工作的唯一工具。我只是说:如果可以,请使用更简单的方法。
2021-04-29 03:07:35
关键是,与其让你的大脑准备好让你的大脑认为箭头函数具有一些特殊的新行为,你现在必须坐下来学习它的含义,将它们视为没有行为要容易得多。是的,如果您在箭头函数中使用它,您可能仍然需要考虑“this”的含义。但这不是箭头函数的错,也不是它添加到组合中的新复杂性。
2021-05-10 03:07:35

这是否意味着当我使用“Fat Arrow”函数中的“this”引用调用函数成员时,“this”总是指封闭的“this”?

您的查询的答案是Yes正如您已经说过的,胖箭头函数没有this引用,因此它们使用封闭上下文的引用,这反过来又让我们有机会控制对this胖箭头函数内部的调用将如何响应。

例如:

在使用的对象内部具有粗箭头函数this将查找外部上下文。在这种情况下,上下文是window

var foo = {
  bar: () => this.baz    // 'this' is window      
}

但是,如果您使用 ES6 语法,即公共类字段语法

class MyClass {
  handleEvent = () => {
    this.letsCode();    // 'this' is instance of MyClass
  }
}

还有许多其他实例(例如在renderHTML 元素上使用React 的函数来设置点击侦听器)超出了这个问题的范围,其中使用了粗箭头函数并this适当地绑定到使用它的上下文,从而给出我们有能力控制其性质。希望能帮助到你!