回调函数中的词法环境是什么?

What is the lexical environment inside a callback function?

我一直听说箭头函数从它们的 Lexical Environment.

继承了 this 的值

考虑这个例子:

let para = document.getElementById("para");
let article = document.getElementById("article");

article.addEventListener("click", () => {
  console.log("I’m a <span> tag!", this);
  event.stopImmediatePropagation();
});
para.addEventListener("click", () => console.log("I’m a <p> tag!", this));
<p id="para">
  <span id="article">Click Me!</span>
</p>

为什么箭头回调函数中this的值是undefined(或者在非严格模式下:window)?如果回调函数使用其词法环境中 this 的值,那么词法环境不应该是 addEventListener 吗?

我认为您应该查看 Arrow Function on MDN 他们充分解释了什么是箭头函数,并将传统函数与箭头函数进行了比较。

根据 MDN:

Arrow function does not have its own bindings to this or super, and should not be used as methods.

因此,在您的情况下,箭头函数不会重新定义 this 这意味着 thiswindow 对象

并且传统的函数被重新定义this从函数的调用。

para.addEventListener("click", function () {
    console.log(this);  // print p node elemnt
});

当您将函数调用为 func(a, b) 时,首先对 a 求值,然后对 b 求值,然后 然后 [=使用 ab 的值调用 18=]。 ab 不是“内部” func

使用以下哪个代码片段并不重要 — 这些是等价的:

const a = () => console.log(this);

addEventListener("click", a);
addEventListener("click", () => console.log(this));

addEventListener 确实 尝试调用其第二个参数 this 设置为事件的 currentTarget,但如 documentation and various other ,箭头函数不能反弹:

"use strict";

(() => console.log(this)).call({ "my": "object" }); // Logs `undefined`.

我不太清楚你说的“词法环境不应该是addEventListener吗?”是什么意思。 箭头函数的词法范围是它创建的范围。 作为一个 arrow function is created,它的作用域和一个特殊的“lexical-this”标志用于创建一个函数对象。 当 called 时,请注意执行 OrdinaryCallBindThis 抽象操作的尝试(通常设置 this)对箭头函数没有任何作用。 相反,函数体在其原始上下文中按原样执行。

再看看你原来的代码,注意每一个 this 都是同一个词法环境的一部分 —— 事实上, this 是一样的,在这段代码中,无论你放在哪里它。 请特别注意,函数参数不会创建新的词法环境。

"use strict";

this; // `undefined`.

let para = document.getElementById("para", this); // Ignored argument, but is `undefined`.
let article = document.getElementById("article");

article.addEventListener("click", () => {
  console.log(this); // Logs `undefined`.
  event.stopImmediatePropagation();
});
para.addEventListener("click", (this, () => console.log(this))); // Logs `undefined`. Preceded by comma operator with discarded value `this`, but would be `undefined`.

相比之下,function 函数会创建一个新的词法环境,并且还可以被反弹:

article.addEventListener("click", function(){
  console.log(this); // Logs `article`.
});

有关更详细的说明,请参阅 How does the “this” keyword work?