簡體   English   中英

箭頭 function 不帶花括號

[英]Arrow function without curly braces

我是 ES6 和 React 的新手,我一直看到箭頭函數。 為什么有些箭頭函數在粗箭頭之后使用花括號,有些使用括號? 例如:

const foo = (params) => (
    <span>
        <p>Content</p>
    </span>
);

對比

const handleBar = (e) => {
    e.preventDefault();
    dispatch('logout');
};

括號返回單個值,花括號執行多行代碼。

您的示例看起來令人困惑,因為它使用的 JSX 看起來像多個“行”,但實際上只是被編譯為單個“元素”。

這里有更多的例子,它們都做同樣的事情:

const a = (who) => "hello " + who + "!";
const b = (who) => ("hello " + who + "!");
const c = (who) => (
  "hello " + who + "!"
);
const d = (who) => (
  "hello "
    + who
    + "!"
);
const e = (who) => {
  return "hello " + who + "!";
}; 

您還經常會在對象文字周圍看到括號,因為這是避免解析器將其視為代碼塊的一種方式:

const x = () => {} // Does nothing
const y = () => ({}) // returns an object

也可以使用花括號來防止單行箭頭函數返回值——或者讓下一個開發人員明白單行箭頭函數在這種情況下不應該返回任何內容。

例如:

const myFunc = (stuff) => { someArray.push(stuff) }
const otherFunc = (stuff) => someArray.push(stuff)

console.log(myFunc())    // --> logs undefined
console.log(otherFunc()) // --> logs result of push which is new array length

括號在箭頭函數中用於返回一個對象。

() => ({ name: 'YourName' })  // This will return an object

這相當於

() => {
   return { name : 'YourName' }
}

實際上在公文包中,當有人在箭頭函數聲明中使用大括號時,它等於以下內容:

const arrow = number => number + 1;

|||

const arrow = (number) => number + 1;

|||    

const arrow = (number) => ( number + 1 );

|||

const arrow = (number) => { return number + 1 };

括號有一個隱式的 return 語句,而花括號你需要一個顯式的 return 語句

在您的第一個示例中,箭頭函數的右側顯示了一個由分組運算符括起來的單個表達式:

const foo = (params) => (
  <span>
    <p>Content</p>
  </span>
);

類似的可比情況如下:

const foo = (params) => (<span><p>Content</p></span>);

在上述使用單個表達式的情況下,區別在於右側是函數的返回值

另一方面,如果您使用花括號, JavaScript會將其理解為語句:

const foo = (params) => {} // this is not an object being returned, it's just an empty statement 

因此,using 語句是您在其中包含多行代碼的良好開端,如果函數打算返回值,則需要使用“return”:

const foo = (params) => {
    let value = 1; 
    return value;
}

如果您想以最短的形式返回一個空對象:

const foo = (params) => ({}) 

查看測試

如果你在箭頭后面使用花括號來定義函數體,你必須使用'return'關鍵字來返回一些東西。

例如:

const myFun1 = (x) => {
    return x;
}; // It will return x

const myFun2 = (x) => {
    x;
}; // It will return nothing

如果使用括號,則無需提及“return”關鍵字。

例如:

const myFunc1 = (x) => x; // It will return x

const myFunc2 = (x) => (x); // It will also return x

要回答重復的帖子( 此處<\/a>發布的問題<\/a>),僅供他人參考:

  var func = x => x * x;                  
    // concise body syntax, implied "return"

    var func = (x, y) => { return x + y; }; 
    // with block body, explicit "return" needed

每個功能都有兩個方面。

首先是每個,不僅僅是箭頭函數,都有一個執行上下文(一個塊作用域),在其中創建和使用變量。

換句話說,在函數的大括號 { ... } 內,在那里聲明和分配的內容保留在那里,並且對外部函數/或變量不可見。

例如,當寫一些東西時

let x = 100;

function doSomething() {
  let x = 50;
  console.log(x);
}

doSomething();     // 50
console.log(x);    // 100

這兩個值都顯示在控制台中(而不是“來自外部的 x 被函數內部的 x 替換”)。

您會看到,盡管let通常不允許再次聲明其他變量 x (使用相同的名稱x ),但在這種情況下,因為第二個 x 在 { ... } 內聲明和初始化,它不會改變外部一個,這也是因為在調用函數doSomething之后,它內部的 x 被創建、分配、打印在控制台中,然后被銷毀(從內存中刪除)。 因此,每次我們通過運行doSomething()調用該函數時都會發生該過程。

所以這是理解函數時要考慮的第一個方面:它們執行然后忘記由花括號內的代碼創建的值。

正因為如此,它們的第二個方面更容易理解——因為函數不能獨立於其他函數工作,它們還需要將數據發送給其他函數,因此它們有一些“報告方面”用於將計算結果的某些部分外部化在他們的花括號內,這正是return語句存在的原因。

return存在於每個函數中,甚至在 console.log 或 alert() 中,甚至在 doSomething() 中,但在這些我們沒有為它顯式設置某些東西的情況下,它總是' return undefined '。

因此沒有必要編寫它,而是知道在您不返回特定內容的地方,函數本身會通過返回 undefined 來為您完成。

當您編寫(或使用)一個僅用於執行某些操作的函數時,它也會返回未定義的。 總是。

您可以使用(顯然)沒有聲明返回的每個函數檢查該內容:

let x = alert(100);
console.log(x); // undefined

let y = doSomething(); // console prints 50
console.log(y);        // 50, then undefined --- 2 lines

console.log(alert('Hello')); // undefined

console.log(console.log('Okay')); // Okay , then undefined

這是為什么?

因為 alert() 是全局對象 window (在瀏覽器中)的一種方法(所以它實際上是 window.alert() )和 console.log() (也與 window.console.log() 相同) ,執行某些操作(在警告框中或控制台中打印() AND THEN return undefined之間的任何內容)。

現在,回到箭頭函數,它們不僅是編寫函數的一些新符號方式,而且還具有一些特定的功能。

首先,如果你在箭頭函數的()之間只有一個參數,你可以寫成不帶括號的。

其次,如果花括號內只有一個語句,您也可以省略花括號。

第三個,如果單條語句是return語句,可以省略return這個詞。

不知何故,如果需要,使用這些我們可以將許多常用函數轉換為箭頭函數:

function doSomething() {let x = 50; console.log(x);} // as function declaration

let doSomething = function() {let x = 50; console.log(x);}; // as function expression, which is an anonymous function assigned to the variable 'doSomething'

let doSomething = () => {let x = 50; console.log(x);}; // as arrow function

// let's transform it further

let doSomething = () => {console.log(50)}; //

// that is equivalent to ---- let doSomething = () => {console.log(50); return undefined};
// or even to           ---- let doSomething = () => {return ( console.log(50) ) };
// because anyways, *console.log* has *return undefined* in it, as explained above

//which is the same as  ---- let doSomething = () => {return console.log(50) };

// let's now apply the rules 2 and 3 from above, one by one:

let doSomething = () => return console.log(50);

let doSomething = () => console.log(50);

// Obviously, this just shows how we could rewrite many usual functions (functions declarations) into arrow functions
// we can do that safely if we don't have any **this** involved in the functions, of course
// also, from all lines of code above only one must remain, for example the last one.

// the last one, despite only having ---- console.log(50) --- as the execution aspect, it also ---- returns undefined ---- as well

// obviously ---- console.log( typeof doSomething );   // function
// while     ---- console.log( typeof doSomething() ); // undefined

如果箭頭函數有 2 個或更多參數,我們不能省略它們周圍的括號:

function sum(a, b) {let total = a + b; return total}

let sum = function(a, b) {let total = a + b; return total};
// or
let sum = (a, b) => {let total = a + b; return total};
// or
let sum = (a, b) => {return a + b};
// or
let sum = (a, b) => a + b;

對於上面的簡單操作,粗箭頭符號'=>'可以被“讀取”為轉換為,換句話說,a 和 b被(被)轉換為a + b。

與此相反,還有一些功能可以驗證一些數據(例如檢查數據類型等),比如這個

let isNumber = x => typeof x === "number";
// or
let isNumber = (x) => {return (typeof x === "number")};
// obviously, 
isNumber("Hello, John!"); // false

那些不轉換數據,因此箭頭符號可以被更多地閱讀為條件 that或類似的東西。

換句話說,像這樣的函數

let double = x => x * 2    // 'double' is a function that transforms x into x*2

與檢查不同(主要用於過濾器、排序和其他類型的驗證函數,通常作為回調函數等)

let isArray = arr => Array.isArray(arr) // that last one already returns boolean by itself, no need to write return (Array.isArray() etc)

關於返回的最后一件事是,當您在多行中編寫代碼時,ASI(自動分號插入)將插入一個';' 如果你在寫完返回字后錯誤地按了回車,這會破壞代碼,因此在返回之后,而不是

return
a+b;

您的代碼將表現為

return;
a+b;

所以你最好用括號編寫代碼,如下所示:

return (
  a + b
);

正如 MDN 網站here中所解釋的那樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM