簡體   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