Javascript 你能在箭头函数中绑定'this'吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33308121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:56:22  来源:igfitidea点击:

Can you bind 'this' in an arrow function?

javascriptfunctionecmascript-6

提问by Florrie

I've been experimenting with ES6 for a while now, and I've just come to a slight problem.

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

I really like using arrow functions, and whenever I can, I use them.

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

However, it would appear that you can't bind them!

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

Here is the function:

这是函数:

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

Here is the object I want to bind the function to:

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

var o = {'a': 42};

And here is how I would bind fto o:

这是我将如何绑定fo

var fBound = f.bind(o);

And then I can just call fBound:

然后我可以打电话fBound

fBound();

Which will output this (the oobject):

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

{'a': 42}

Cool! Lovely! Except that it doesn't work. Instead of outputting the oobject, it outputs the windowobject.

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

So I'd like to know: can you bind arrow functions? (And if so, how?)

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



I've tested the code above in Google Chrome 48 and Firefox 43, and the result is the same.

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

回答by Nick Tomlin

You cannot rebindthisin an arrow function. It will always be defined as the context in which it was defined. If you require thisto be meaningful you should use a normal function.

您不能在箭头函数中重新绑定this。它总是被定义为在其被定义的上下文。如果您需要this有意义,你应该使用一个正常功能。

From the ECMAScript 2015 Spec:

ECMAScript的2015年规格

Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function.

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

回答by cvazac

To be complete, you canre-bind arrow functions, you just can't change the meaning of this.

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

bindstill has value for function arguments:

bind还有函数参数值:

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

Try it here: http://jsbin.com/motihanopi/edit?js,console

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

回答by Sterling Archer

From the MDN:

来自MDN

An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous.

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

This means you cannot bind a value to thislike you want.

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

回答by taxicala

For years, js developers struggled with context binding, asked why thischanged in javascript, so much confusion over the years due to context binding and the difference between the meaning of thisin javascript and thisin most of the other OOP languages.

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

All this leads me to ask, why, why! why would you wan't to rebind an arrow function! Those where created specially to solve all this issues and confusions and avoid having to use bindor callor whatever other way to preserve the scope of the function.

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

TL;DR

TL; 博士

No, you cannot rebind arrow functions.

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

回答by theName

You cannot use bindto change the value of thisinside an arrow function. However, you can create a new regular function that does the same thing as the old arrow function and then use callor bindto re-bind thisas usual.

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

We use an evalcall here to recreate the arrow function you pass in as a normal function and then use callto invoke it with a different 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)});

回答by Prithvi Raj Vuppalapati

Do ES6 Arrow Functions Really Solve “this” In JavaScript

ES6 箭头函数真的解决了 JavaScript 中的“this”

The above link explains that arrow functions thisdoesn't change with bind, call, applyfunctions.

上面的链接解释了箭头函数this不会随着bind, call, apply函数而改变。

It is explained with a very nice example.

它用一个非常好的例子来解释。

run this in node v4to see the "expected" behavior,

运行它node v4以查看“预期”行为,

this.test = "attached to the module";
var foo = { test: "attached to an object" };
foo.method = function(name, cb){ 
    // bind the value of "this" on the method 
    // to try and force it to be what you want 
    this[name] = cb.bind(this); };
foo.method("bar", () => { console.log(this.test); });
foo.bar(); 

回答by fos.alex

I asked the same question a couple days ago.

几天前我问了同样的问题。

You cannot bind a value since the thisis already binded.

您无法绑定值,因为this已经绑定。

Binding different this scope to ES6 => function operator

将不同的 this 作用域绑定到 ES6 => 函数运算符

回答by Ehsan

Maybe this example help to you :

也许这个例子对你有帮助:

let bob = {
   _name: "Bob",
   _friends: ["stackoverflow"],
   printFriends:(x)=> {
      x._friends.forEach((f)=> {
         console.log(x._name + " knows " + f);
      });
   }
}

bob.printFriends = (bob.printFriends).bind(null,bob);
bob.printFriends();

回答by Alireza

Short, You CAN NOTbind arrow functions, but read on:

简而言之,您不能绑定箭头函数,但请继续阅读:

Imagine you have this arrow function below which console this:

想象一下,您在控制台下方有这个箭头函数this

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

So the quick fix for this would be using normal function, so just change it to:

因此,对此的快速修复将使用普通功能,因此只需将其更改为:

function myFunc() {console.log(this)};

Then you can bind it to any lexical environment using bindor callor apply:

然后,你可以用它绑定到任何词法环境bindcallapply

const bindedFunc = myFunc.bind(this);

and call it in case of bind.

并在 的情况下调用它bind

bindedFunc();

There are also ways to using eval()to do it, which strongly not recommend.

还有一些方法可以eval()用来做,强烈不推荐.