Kapan saya harus menggunakan `return` di es6 Arrow Functions?

Jawaban:

262

Jackson telah sebagian menjawab ini dalam pertanyaan serupa:

Pengembalian tersirat, tetapi hanya jika tidak ada blok.

  • Ini akan menghasilkan kesalahan ketika satu-baris diperluas ke beberapa baris dan programmer lupa untuk menambahkan return.
  • Pengembalian implisit sintaksis ambigu. (name) => {id: name}mengembalikan objek {id: name}... kan? Salah. Ia kembali undefined. Kawat gigi itu adalah blok eksplisit. id:adalah label.

Saya akan menambahkan definisi blok :

Pernyataan blok (atau pernyataan majemuk dalam bahasa lain) digunakan untuk mengelompokkan nol atau lebih pernyataan. Blok dibatasi oleh sepasang kurung keriting.

Contoh :

// returns: undefined
// explanation: an empty block with an implicit return
((name) => {})() 

// returns: 'Hi Jess'
// explanation: no block means implicit return
((name) => 'Hi ' + name)('Jess')

// returns: undefined
// explanation: explicit return required inside block, but is missing.
((name) => {'Hi ' + name})('Jess')

// returns: 'Hi Jess'
// explanation: explicit return in block exists
((name) => {return 'Hi ' + name})('Jess') 

// returns: undefined
// explanation: a block containing a single label. No explicit return.
// more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label
((name) => {id: name})('Jess') 

// returns: {id: 'Jess'}
// explanation: implicit return of expression ( ) which evaluates to an object
((name) => ({id: name}))('Jess') 

// returns: {id: 'Jess'}
// explanation: explicit return inside block returns object
((name) => {return {id: name}})('Jess') 
Jess Telford
sumber
Saya tidak mendapatkan sintaks itu .. apakah Anda membuat kelas menggunakan littoral kelas dan kemudian memanggil konstruktor tersirat dengan satu argumen ('Jess') ?? Saya pikir Anda akan melakukan ini ((nama) => ({id: 'Jess'}))
Michael Dausmann
3
@MichaelDausmann Ini adalah fungsi panah yang memiliki satu parameter name,, dengan fungsi terlampir dalam tanda kurung dan dipanggil dengan satu argumen, "Jess". Kode antara =>dan )('Jess')dalam setiap kasus adalah badan fungsi panah. Anggap saja sebagai bentuk singkat dari Ekspresi Fungsi yang Segera Diminta dari formulir(function (name) { return { id: name } })('Jess')
Russ Cam
Diinduksi sangat berguna! membantu mengatasi masalah di Promises.all yang memetakan item dengan fungsi panah dan Anda dapat melihat jika Anda mendapatkan array yang tidak terdefinisi jika tidak ada nilai yang dikembalikan untuk pemetaan lebih dari array dengan fungsi panah.
jay shah
Apa yang menjadi kelemahan dari membuat pengembalian implisit sistematis untuk fungsi panah? Sama seperti coffeescript tidak ... (meskipun saya tidak suka coffeescript)
Augustin Riedinger
4
Untuk menjadi jelas, tampaknya karena parser JS tidak tahu apakah mengharapkan ekspresi (seperti ekspresi yang mengandung objek literal {}) atau blok , itu mengasumsikan bahwa { }menunjukkan suatu blok. Itu berarti bahwa ketika dilihat id: name, ia berpikir id:adalah ekspresi yang menciptakan label (fitur JS yang sangat jarang digunakan yang berhubungan dengan kontrol aliran dan penggunaan a :), dan kemudian yang nameberikut id:hanyalah pernyataan terpisah yang hanya berisi variabel name(& tidak melakukan apa-apa).
iono
18

Saya mengerti aturan praktis ini ...

Untuk fungsi yang secara efektif mengubah (manipulasi argumen satu baris), return bersifat implisit.

Calon adalah:

// square-root 
value => Math.sqrt(value)

// sum
(a,b) => a+b

Untuk operasi lain (lebih dari satu-liner yang memerlukan blok, return harus eksplisit

Amarsh
sumber
11

Ada kasus lain di sini.

Saat menulis komponen fungsional dalam Bereaksi, Anda dapat menggunakan tanda kurung untuk membungkus JSX yang dikembalikan secara implisit.

const FunctionalComponent = () => (
  <div>
    <OtherComponent />
  </div>
);
Deci
sumber
4
Anda selalu dapat menggunakan tanda kurung, itu tidak terkait dengan BEJ atau Bereaksi.
Emile Bergeron
4

Ini kasus lain yang memberiku masalah.

// the "tricky" way
const wrap = (foo) => (bar) => {
  if (foo === 'foo') return foo + ' ' + bar;
  return 'nofoo ' + bar;
}

Di sini kita mendefinisikan suatu fungsi yang mengembalikan fungsi anonim. Bit "yang rumit" adalah bahwa badan fungsi untuk fungsi luar (bagian yang diawali dengan (bar) => ...) secara visual tampak seperti "blok", tetapi sebenarnya tidak. Karena tidak, pengembalian secara implisit akan dimulai.

Inilah cara wrap akan dijalankan:

// use wrap() to create a function withfoo()
const withfoo = wrap('foo');
// returns: foo bar
console.log(withfoo('bar'));

// use wrap() to create a function withoutfoo()
const withoutfoo = wrap('bar');
// returns: nofoo bar
console.log(withoutfoo('bar'));

Cara saya membongkar ini untuk memastikan saya mengerti itu adalah untuk "tidak menjelaskan" fungsi.

Berikut ini ekuivalen semantik dari blok kode pertama, cukup membuat tubuh wrap () melakukan pengembalian eksplisit. Definisi ini menghasilkan hasil yang sama seperti di atas. Di sinilah titik-titik terhubung. Bandingkan blok kode pertama di atas dengan yang di bawah ini, dan jelas bahwa fungsi panah itu sendiri diperlakukan sebagai ekspresi, bukan blok, dan memiliki pengembalian tersirat .

// the explicit return way
const wrap = (foo) => {
  return (bar) => {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  }
}

Versi bungkus yang sepenuhnya tidak berbentuk akan seperti ini, yang walaupun tidak sekompak versi panah gemuk, tampaknya jauh lebih mudah untuk dipahami.

// the "no arrow functions" way
const wrap = function(foo) {
  return function(bar) {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  };
};

Pada akhirnya, untuk orang lain yang mungkin harus membaca kode saya, dan masa depan saya, saya pikir saya lebih suka untuk pergi versi non panah yang dapat dipahami secara visual pada pandangan pertama, daripada panah yang mengambil sedikit berpikir (dan dalam eksperimen kasus saya) untuk grok.

grayjohn
sumber
3

Fungsi panah memungkinkan Anda memiliki pengembalian implisit: nilai dikembalikan tanpa harus menggunakan return kata kunci.

Ini berfungsi ketika ada pernyataan on-line di badan fungsi:

const myFunction = () => 'test'

console.log(myFunction()) //'test'

Contoh lain, mengembalikan objek (ingat untuk membungkus kurung keriting dalam tanda kurung untuk menghindari itu dianggap sebagai tanda kurung fungsi tubuh pembungkus):

const myFunction = () => ({value: 'test'})

console.log(myFunction()) //{value: 'test'}

Flavio Copes
sumber
1
Ini harus menjadi jawaban yang benar, meskipun perlu penjelasan lebih lanjut. Pada dasarnya ketika fungsi tubuh adalah ekspresi, bukan blok, nilai ekspresi itu dikembalikan secara implisit. Koreksi saya jika saya salah.
Paul-Sebastian Manole