有人可以给我简单介绍一下词法 this 吗?
“与函数表达式相比,箭头函数表达式(也称为胖箭头函数)的语法更短,并且在词法上绑定了 this 值(不绑定自己的 this、arguments、super 或 new.target)。箭头函数总是匿名的.”
这是否意味着当我使用“Fat Arrow”函数中的“this”引用调用函数成员时,“this”总是指封闭的“this”?
有人可以给我简单介绍一下词法 this 吗?
“与函数表达式相比,箭头函数表达式(也称为胖箭头函数)的语法更短,并且在词法上绑定了 this 值(不绑定自己的 this、arguments、super 或 new.target)。箭头函数总是匿名的.”
这是否意味着当我使用“Fat Arrow”函数中的“this”引用调用函数成员时,“this”总是指封闭的“this”?
您似乎对this
箭头函数中发生的事情有正确的理解。我将提供一个我认为有助于对话的解释,并希望能巩固您的理解。
您可能知道,当您定义一个函数并在其中使用一个变量时,它会检查该变量是否已在其作用域中定义。如果是,它会使用它!如果不是,它会检查该变量定义的封闭范围。它不断检查封闭作用域,直到找到变量或到达全局作用域。现在,不是箭头函数的函数定义this
为您隐式定义。因此,当您尝试this
在它们的作用域中使用时,它们永远不会检查封闭作用域(因为它们在它们自己的作用域中找到它!)。箭头函数不定义它们自己的this
,因此它们会转到封闭的作用域并查找它,就像它们在您尝试在其作用域中使用的任何变量一样。
作为描述this
箭头函数行为的一种方式,术语“词法this
”介于混淆和错误之间。
行为很简单,this
在箭头函数中是指this
在周围的函数中——或者说箭头函数没有定义(或“绑定”)它自己的this
.
不幸的是,“词法this
”这个术语可能是由于MDN 文章中关于箭头函数的措辞选择不当(直到最近还鼓励人们使用过时的术语“胖箭头函数”)。现在已经清理干净了。另请注意,规范从不使用与this
in 箭头函数相关的术语“词法” 。我很想知道是谁提出了这个表达。
假设您有一个点击侦听器。在该侦听器中,您正在执行一些 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”。
这是否意味着当我使用“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
}
}
还有许多其他实例(例如在render
HTML 元素上使用React 的函数来设置点击侦听器)超出了这个问题的范围,其中使用了粗箭头函数并this
适当地绑定到使用它的上下文,从而给出我们有能力控制其性质。希望能帮助到你!