你能在箭头函数中绑定“this”吗?

IT技术 javascript function ecmascript-6
2021-01-16 10:21:22

我已经尝试使用 ES6 一段时间了,但我遇到了一个小问题。

我真的很喜欢使用箭头函数,只要有可能,我就会使用它们。

但是,您似乎无法绑定它们!

这是函数:

var f = () => console.log(this);

这是我要将函数绑定到的对象:

var o = {'a': 42};

这是我将如何绑定fo

var fBound = f.bind(o);

然后我可以打电话fBound

fBound();

这将输出这个(o对象):

{'a': 42}

凉爽的!迷人的!除了它不起作用。它不是输出o对象,而是输出window对象。

所以我想知道:你能绑定箭头函数吗?(如果是这样,如何?)


我已经在 Google Chrome 48 和 Firefox 43 中测试了上面的代码,结果是一样的。

6个回答

您不能在箭头函数中重新绑定 this它将始终被定义为定义它的上下文。如果您需要this有意义,则应使用正常功能。

来自ECMAScript 2015 规范

ArrowFunction 中对参数、super、this 或 new.target 的任何引用都必须解析为词法封闭环境中的绑定。通常,这将是直接封闭函数的函数环境。

完整地说,你可以重新绑定箭头函数,你只是不能改变this.

bind 仍然具有函数参数的value:

((a, b, c) => {
  console.info(a, b, c) // 1, 2, 3
}).bind(undefined, 1, 2, 3)()

在这里试试:http : //jsbin.com/motihanopi/edit?js,console

使用上下文参数: ((context) => { someOtherFunction.apply(context) }).bind(willBeIgnored, context)()
2021-03-23 10:21:22
有没有办法检测或使用(箭头)函数绑定到的任何对象,而无需引用this(当然,这是词法定义的)?
2021-03-27 10:21:22

来自MDN

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

这意味着你不能this像你想要的那样绑定一个值

您不能用于bind更改this箭头函数内部的值但是,您可以创建一个新的常规函数​​,它与旧的箭头函数执行相同的操作,然后像往常一样使用callbind重新绑定this

我们eval在此处使用调用来重新创建您作为普通函数传入的箭头函数,然后使用call不同的 调用它this

var obj = {value: 10};
function arrowBind(context, fn) {
  let arrowFn;
  (function() {
    arrowFn = eval(fn.toString());
    arrowFn();
  }).call(context);
}
arrowBind(obj, () => {console.log(this)});

多年来,js 开发人员一直在为上下文绑定而苦苦挣扎,问为什么thisjavascript 发生了变化,由于上下文绑定以及thisjavascript 和this大多数其他 OOP 语言中的含义之间的差异,多年来造成了如此多的混乱

这一切让我不禁要问,为什么,为什么!你为什么不想重新绑定箭头函数!那些专门为解决所有这些问题和混淆而创建的,并避免必须使用bindcall或任何其他方式来保留函数的范围。

TL; 博士

不,您不能重新绑定箭头函数。

首先创建箭头函数是为了提供更清晰、更快的语法。想想 lambda 演算。太糟糕了,困扰着函数式 JS 程序员生活的 OO 狂热者抓住了机会,剥夺了指定调用上下文的自由。
2021-03-13 10:21:22
使用this不起作用。lambdas 应该是arguments => output. 如果您需要一些外部上下文,请将其传入。正是因为它的存在this促进了将 OO 模式硬塞进语言中的所有内容。如果没有它,您将永远不会听说过“javascript 类”这个词。
2021-03-24 10:21:22
这是重新绑定的一个用例:describe("Test suite", () => { before(function () { if (conditionIsNotMet) this.skip(); // skip the suite } });如果将该函数更改为箭头函数,则 this.skip 将丢失。
2021-03-27 10:21:22
可以重新绑定箭头函数。只是没有this
2021-03-31 10:21:22