回调箭头函数中的这个值是什么?[复制]

What's the this value in callback arrow functions? [duplicate]

提问人:Abdullah Binsaad 提问时间:9/28/2023 最后编辑:Abdullah Binsaad 更新时间:9/28/2023 访问量:71

问:

因此,当我阅读 javascript 中的执行上下文及其工作原理时,一切似乎都很好,直到我尝试了一些关于回调箭头函数的 this 值的示例。

const printCard = function () {
  this.signatories.forEach((signatory) =>
    console.log(this) /* expected to return signatories, returned messageConfig */
  );
};

const messageConfig = {
  closing: {
    Thor: "Admiration, respect, and love",
    Loki: "Your son",
  },
  signatories: ["Thor", "Loki"],
};

printCard.call(messageConfig);

在这里,由于 forEach 是签名者的原型方法,我希望回调(箭头函数)自动从封闭上下文(在本例中为 forEach)中获取 this 值。但是,它似乎返回了 messageConfig,这让我想起了词法范围。

javascript 回调 这个 arrow-functions executioncontext

评论

0赞 Samathingamajig 9/28/2023
“封闭上下文”是你创建的函数(带有关键字)函数,在这种情况下,它具有“封闭上下文”messageConfig
1赞 Jaromanda X 9/28/2023
the enclosing context不是你想象的那样 - 在...这就是箭头函数console.log(this);forEachthis
1赞 Barmar 9/28/2023
forEach()在调用其函数时不传递上下文。即使这样做了,箭头函数也会忽略传递给它们的上下文,它们会从定义它们的作用域绑定上下文。this
1赞 Barmar 9/28/2023
所以 in 中的箭头函数和 中的相同。thisthisprintCard
0赞 Barmar 9/28/2023
传递给回调函数的第三个参数是正在迭代的数组。所以forEach()forEach((signatory, i, signatories) => ...)

答:

0赞 Alexander Nenashev 9/28/2023 #1

箭头函数只是从外部作用域借用 and(它没有自己的)。外部作用域是用 、 参数和 调用的。您可以使用或使用第三个参数访问数组,该数组是被迭代的数组。thisargumentsprintCard()this = messageConfigarg1arg2this.signatoriesforEach()

箭头函数作为方法内部的回调很有用,因为您在它们内部有一个实例来调用方法,因此不需要像通常那样进行 bind/call/apply/self 。thisfunction

const printCard = function () {
  this.signatories.forEach((signatory, i, arr) => {
    console.log(arguments);
    console.log(this.signatories);
    console.log(arr);
  });
};

const messageConfig = {
  closing: {
    Thor: "Admiration, respect, and love",
    Loki: "Your son",
  },
  signatories: ["Thor", "Loki"],
};

printCard.call(messageConfig, 'arg1', 'arg2');

1赞 Barmar 9/28/2023 #2

Array.prototype.forEach()不会将数组作为上下文传递给其回调函数。它将循环的数组作为第三个参数传递。因此,如果您想获得签名者,请使用this

const printCard = function () {
  this.signatories.forEach((signatory, i, signatories) =>
    console.log(signatories);
  );
};

您可以选择将第二个参数传递给,该参数将作为上下文传递。forEach()this

但是,箭头函数不接受传递的上下文,因此这无济于事。它们从定义范围继承上下文。由于您在使用 时将上下文绑定到 ,这是 in 的值,也是回调函数的值。thismessageConfigprintCard.call()thisprintCard()

如果要将回调函数更改为常规函数,则将是浏览器中的对象或 node.js 中的对象,除非代码处于严格模式。thiswindowglobal

评论

1赞 InSync 9/28/2023
虽然确实将迭代的数组作为第三个参数传递给回调,但它也接受第二个参数作为该回调内部使用。.forEach()this
0赞 Barmar 9/28/2023
完全忘记了这个功能(甚至比 cb 的第三个论点更晦涩难懂)。我已经更新了答案。