Saya terjebak dengan konsep 'Fungsi yang mengembalikan fungsi'. Saya merujuk pada buku 'Object Oriented Javascript' oleh Stoyan Stefanov.
Cuplikan Satu:
function a() {
alert('A!');
function b(){
alert('B!');
}
return b();
}
var s = a();
alert('break');
s();
Keluaran:
A!
B!
break
Cuplikan Dua
function a() {
alert('A!');
function b(){
alert('B!');
}
return b;
}
var s = a();
alert('break');
s();
A!
break
B!
Bisakah seseorang memberi tahu saya perbedaan antara kembali b
dan b()
di cuplikan di atas?
javascript
Cafecorridor
sumber
sumber
Jawaban:
Menetapkan variabel ke suatu fungsi (tanpa tanda kurung) akan menyalin referensi ke fungsi tersebut. Menempatkan tanda kurung di akhir nama fungsi, memanggil fungsi, mengembalikan nilai hasil fungsi.
Demo
Dalam contoh Anda, Anda juga mendefinisikan fungsi dalam suatu fungsi. Seperti:
Fungsinya masih bisa dipanggil. Itu masih ada. Ini digunakan di JavaScript sepanjang waktu. Fungsi dapat diedarkan hanya seperti nilai-nilai lain. Pertimbangkan hal berikut:
Hitungan fungsi dapat menyimpan variabel yang didefinisikan di luarnya. Ini disebut penutupan. Ini juga banyak digunakan dalam JavaScript.
sumber
this
hanya berarti sesuatu di dalam tubuh fungsi, jika tidak maka global. Maksud Andathis.sayName
adalah bahwa Anda menginginkan variabel globalsayName
yang tidak ada, tidak ditentukan, jadi tidak dapat dipanggil.Mengembalikan nama fungsi tanpa
()
mengembalikan referensi ke fungsi tersebut, yang dapat ditetapkan setelah Anda selesaivar s = a()
.s
sekarang berisi referensi ke fungsi tersebutb()
, dan pemanggilans()
secara fungsional setara dengan pemanggilanb()
.Memanggil fungsi dengan
()
pernyataan return akan menjalankan fungsi tersebut, dan mengembalikan nilai apa pun yang dikembalikan oleh fungsi tersebut. Ini mirip dengan memanggilvar x = b();
, tetapi alih-alih menetapkan nilai kembalianb()
Anda mengembalikannya dari fungsi panggilana()
. Jika fungsinyab()
sendiri tidak mengembalikan nilai, panggilan akan kembaliundefined
setelah pekerjaan lain apa pun yang dilakukanb()
.sumber
return b();
memanggil fungsi b (), dan mengembalikan hasilnya.return b;
mengembalikan referensi ke fungsi b, yang bisa Anda simpan dalam variabel untuk dipanggil nanti.sumber
Kembali
b
adalah mengembalikan objek fungsi. Dalam Javascript, fungsi hanyalah objek, seperti objek lainnya. Jika menurut Anda itu tidak membantu, ganti saja kata "object" dengan "thing". Anda dapat mengembalikan objek apa pun dari suatu fungsi. Anda dapat mengembalikan nilai benar / salah. Integer (1,2,3,4 ...). Anda dapat mengembalikan string. Anda dapat mengembalikan objek kompleks dengan beberapa properti. Dan Anda bisa mengembalikan fungsi. sebuah fungsi hanyalah sebuah benda.Dalam kasus Anda, mengembalikan
b
mengembalikan benda, benda itu adalah fungsi yang dapat dipanggil. Mengembalikanb()
mengembalikan nilai yang dikembalikan oleh fungsi yang dapat dipanggil.Pertimbangkan kode ini:
Menggunakan definisi di atas,
return b();
mengembalikan nilai 42. Di sisi lainreturn b;
mengembalikan sebuah fungsi, yang dengan sendirinya mengembalikan nilai 42. Mereka adalah dua hal yang berbeda.sumber
42
;)Saat Anda kembali
b
, itu hanya referensi ke fungsi b, tetapi tidak dijalankan saat ini.Saat Anda kembali
b()
, Anda menjalankan fungsi dan mengembalikan nilainya.Coba
alert
ingtypeof(s)
di contoh Anda. Snippet b akan memberi Anda 'fungsi'. Apa yang akan diberikan snippet a kepada Anda?sumber
s
. Cobalahreturn this
alih-alihreturn b
… Anda akan dapat melakukannyas.b()
;)Bayangkan fungsinya sebagai tipe, seperti int. Anda dapat mengembalikan int dalam suatu fungsi. Anda juga dapat mengembalikan fungsi, mereka adalah objek bertipe "fungsi".
Sekarang masalah sintaks: karena fungsi mengembalikan nilai, bagaimana Anda bisa mengembalikan fungsi dan bukan mengembalikan nilai?
dengan menghilangkan tanda kurung! Karena tanpa tanda kurung, fungsi tidak akan dijalankan! Begitu:
Akan mengembalikan "fungsi" (bayangkan seperti jika Anda mengembalikan angka), sedangkan:
Pertama jalankan fungsinya lalu kembalikan nilai yang diperoleh dengan mengeksekusinya, itu perbedaan besar!
sumber
Buat variabel :
Deklarasikan Fungsi :
Waspada nilai dari
thing1
(variabel pertama kami):Sekarang, jika kita ingin
thing1
menjadi referensi ke fungsi tersebutsomething1
, artinya itu akan sama dengan fungsi yang kita buat, kita akan melakukan:Namun, jika kita menginginkan
return
nilai dari fungsi tersebut maka kita harus menetapkannya nilai kembali dari fungsi yang dieksekusi. Anda menjalankan fungsi dengan menggunakan tanda kurung:sumber
Cuplikan satu:
pernyataan 'b ()' berarti menjalankan fungsi bernama 'b' yang menampilkan kotak dialog dengan teks 'B!'
pernyataan 'return b ();' berarti menjalankan fungsi bernama 'b' dan kemudian mengembalikan fungsi 'b' apa yang dikembalikan. tetapi 'b' tidak menghasilkan apa-apa, maka pernyataan 'return b ()' ini juga tidak mengembalikan apa-apa. Jika b () mengembalikan angka, maka 'return b ()' juga merupakan angka.
Sekarang 's' diberi nilai apa 'a ()' return, yang mengembalikan 'b ()', yang tidak berarti apa-apa, jadi 's' bukan apa-apa (dalam JavaScript itu sebenarnya, itu 'tidak terdefinisi'. Jadi ketika Anda meminta JavaScript untuk menafsirkan tipe data apa 's', penerjemah JavaScript akan memberi tahu Anda 's' adalah tidak terdefinisi.) As 's' adalah tidak terdefinisi, ketika Anda meminta JavaScript untuk mengeksekusi pernyataan ini 's ()', Anda meminta JavaScript untuk menjalankan fungsi bernama 's', tetapi 's' di sini adalah 'tidak ditentukan', bukan fungsi, jadi JavaScript akan mengeluh, "hei, s bukan fungsi, saya tidak tahu caranya untuk dilakukan dengan "s ini, maka pesan kesalahan" Uncaught TypeError: s is not a function "akan ditampilkan oleh JavaScript (diuji di Firefox dan Chrome)
Cuplikan Dua
sekarang, fungsi 'a' mengembalikan pointer / alias ke fungsi bernama 'b'. jadi ketika mengeksekusi 's = a ()', 's' akan mendapatkan nilai yang menunjuk ke b, yaitu 's' adalah alias dari 'b' sekarang, memanggil 's' sama dengan memanggil 'b'. ie 's' adalah fungsi sekarang. Jalankan 's ()' berarti menjalankan fungsi 'b' (sama seperti menjalankan 'b ()'), kotak dialog yang menampilkan 'B!' akan muncul (yaitu menjalankan 'alert (' B! '); pernyataan dalam fungsi' b ')
sumber
Ini sangat berguna dalam kehidupan nyata.
Bekerja dengan Express.js
Jadi,
express
rute reguler Anda terlihat seperti ini:Tetapi bagaimana jika Anda perlu menambahkan beberapa pembungkus, penanganan kesalahan atau sesuatu?
Kemudian Anda menjalankan fungsi Anda dari pembungkus.
Terlihat rumit? Nah, bagaimana dengan ini:
Lihat di bagian akhir Anda meneruskan fungsi yang
loggingWrapper
memiliki satu argumen sebagai fungsi lainitWorksHandler
, dan AndaloggingWrapper
mengembalikan fungsi baru yang mengambilreq, res, next
argumen.sumber