回调函数中的词法环境是什么?
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
这意味着 this
是 window
对象
并且传统的函数被重新定义this
从函数的调用。
para.addEventListener("click", function () {
console.log(this); // print p node elemnt
});
当您将函数调用为 func(a, b)
时,首先对 a
求值,然后对 b
求值,然后 然后 [=使用 a
和 b
的值调用 18=]。
a
和 b
不是“内部” 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?。
我一直听说箭头函数从它们的 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
这意味着 this
是 window
对象
并且传统的函数被重新定义this
从函数的调用。
para.addEventListener("click", function () {
console.log(this); // print p node elemnt
});
当您将函数调用为 func(a, b)
时,首先对 a
求值,然后对 b
求值,然后 然后 [=使用 a
和 b
的值调用 18=]。
a
和 b
不是“内部” 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?。