繁体   English   中英

箭头功能和这个

[英]arrow function and this

我正在浏览Twitter,发现了以下推文:

https://twitter.com/_ericelliott/status/855598297939144704

这是推文中的代码:

const double = () => this.x * 2;
const numDouble = double.bind({ x: 5 });
numDouble();

当您在控制台中运行此代码段时,它将生成NaN。 怎么样? 作者显式绑定x的值,但仍显示NaN。

作者还指定了箭头功能不能绑定此功能。 据我所知,箭头功能在词法上绑定了这种形式的范围周围的值。 那为什么作者这么宣称呢?

请澄清我的疑问,并在此先感谢您的帮助。

箭头功能不结合this 根据MDN:

没有约束力

直到箭头的功能,每一个新的函数来定义其自己的this值(在一个构造的情况下,一个新的对象,在严格模式的函数调用,如果该函数被称为“对象方法”等上下文对象未定义)。 事实证明,这是一种面向对象的编程风格,令人讨厌。

所以, this在你的榜样将是全局对象window ,这显然没有叫物业x

例:

 function foo() { let arrow = () => { console.log(this); // will use foo's this as arrow will never have its own this } arrow.call({"x": "x"}); // ... even if we specify it using bind, call, or apply } foo.call({"y": "y"}); // specifying the this for foo (this value will eventually be used by arrow because it will be availbale in its scope) 

要记住的关键是:

  • 箭头函数 this 关闭, this恰好是函数在变量上关闭的方式。 (事实上,这是相同的机制。)不管this是在其中创建箭头的功能是什么this将是该箭头函数的调用过程。 再也没有其他了。 箭函数忽略了this他们称之为有。

如果您还记得这一点,那么您再也不会在箭头功能中this感到困惑。

当您在控制台中运行此代码段时,它将生成NaN。 怎么样? 作者显式绑定x的值,但仍显示NaN。

numDouble = double.bind({ x: 5 })创建一个新的功能( numDouble ),调用它时,将调用原始功能( double )与this设定为您提供作为值bind的第一个参数( { x: 5 } )。 但是,由于箭头的功能忽略了this他们称之为有, bind无法控制this ,他们使用。

作者还指定了箭头功能不能绑定此功能。 据我所知,箭头功能在词法上绑定了这种形式的范围周围的值。

是的,这意味着您无法更改它。 词汇绑定是闭包的工作方式。 此箭头功能:

const a = () => {
    console.log(typeof this);
};

对待this正是这种传统的功能对待的方式thisWhereFunctionWasCreated

const thisWhereFunctionWasCreated = this;
const t = function() {
    console.log(typeof thisWhereFunctionWasCreated);
};

就像你不能改变什么thisWhereFunctionWasCreatedt的用途时,你怎么称呼它,你不能改变this a ,当你调用它的用途。 (如果thisWhereFunctionWasCreated不是const ,则可以更改其持有的 ,但不能thisWhereFunctionWasCreated变量 t使用的值。但是在该示例中它是一个常量,因为this是一个常量。)

由于箭头功能完全忽略了this ,它被称为用,它不会不管你用什么机制来试图告诉箭头的功能是什么this来使用,它不会工作。 是否指定this通过调用函数作为方法(隐式obj.arrow()或通孔) callapplyarrow.call(obj)或通过bindconst boundArrow = arrow.bind(obj); boundArrow(); ),它仍会使用它关闭的this代替:

 "use strict"; function Ctor() { // `this` will be the object created by `new Ctor`; grab it this.name = "outerThis"; const outerThis = this; // `traditional` doesn't close over `this`, so you CAN change // what `this` it uses when you call it, in various ways function traditional(testNum) { console.log(testNum, "traditional:", getName(this)); } // `arrow` closes over `this`, so you CAN'T change // what `this` it uses when you call it const arrow = testNum => { console.log(testNum, "arrow: ", getName(this)); }; // Remember that the `this` in a direct call is the global // object in loose mode, `undefined` in strict mode; this // code is in strict mode console.log("Direct call (default `this`):"); traditional(1); // 1 traditional: window arrow(1); // 1 arrow: outerThis console.log("`obj.xyz()`:"); const obj = { name: "obj", arrow, traditional }; obj.traditional(2); // 2 traditional: obj obj.arrow(2); // 2 arrow: outerThis console.log("Using `call`:"); traditional.call(obj, 3); // 3 traditional: obj arrow.call(obj, 3); // 3 arrow: outerThis console.log("Using `bind` and calling result:"); const boundTraditional = traditional.bind(obj); const boundArrow = arrow.bind(obj); boundTraditional(4); // 4 traditional: obj boundArrow(4); // 4 arrow: outerThis } function getName(t) { switch (t) { case undefined: return "undefined"; case window: return "window"; default: return t.name; } } new Ctor(); 
 .as-console-wrapper { max-height: 100% !important; } 

当在箭头函数上调用bind时, bind唯一可以做的就是绑定参数:

 const arrow = (x, y) => x + y; console.log(arrow(2, 3)); // 5 const arrowWith2 = arrow.bind(null, 2); console.log(arrowWith2(3)); // 5 const arrowWith2And3 = arrow.bind(null, 2, 3); console.log(arrowWith2And3()); // 5 

(它还将结果函数的名称设置为"bound x" [其中x是原始函数的名称。因此,上面的arrowWith2.name"bound arrow" 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM