Deklarasi fungsi sebagai var bukan fungsi

28

Semakin banyak saya melihat fungsi yang dideklarasikan seperti

var foo = function() {

    // things
};

Alih-alih bagaimana saya telah belajar, seperti

function foo() {

    // things
}

Apa bedanya? Performa yang lebih baik? Cakupan? Haruskah saya menggunakan metode ini?

Steve Robbins
sumber
Perlu dicatat bahwa dalam javascript, fungsi adalah warga negara kelas satu . Ini memungkinkan Anda untuk menyampaikan perilaku seperti objek. Ini sangat berguna untuk callback dan delegasi, antara lain.
Chris Bye
Lingkup . Nama variabel pembungkus "// things" pada dasarnya / semoga mencegah tabrakan nama dari "// things" yang dibungkusnya, dengan JavaScript (file) lainnya disertakan. Cara lain untuk memikirkannya adalah bahwa Anda telah membuat namespace "foo".
radarbob

Jawaban:

25

var foo = function() {} mendefinisikan variabel yang mereferensikan fungsi anonim.

function foo() {}mendefinisikan fungsi bernama foo.

Entah dapat diluluskan dengan nama sebagai parameter fungsi dan juga dapat dipakai jika penggunaan yang dimaksudkan adalah untuk OOP.

Pada akhirnya, yang Anda gunakan sebagian besar ditentukan oleh kasus penggunaan khusus Anda (Javascript menyenangkan seperti itu;)). Jika Anda akhirnya menggunakan yang pertama, saya sangat menyarankan Anda memberi nama fungsi:

var foo = function MY_function() {}. Konvensi penamaan ini membantu callstack debugger Anda tidak sia-sia.

Demian Brecht
sumber
1
Ada kesalahan fungsi () SAYA ...
Erik Reppen
1
@ Demian Brecht, dan bagaimana dengan pendekatan var foo = function foo () {...}?
shabunc
@shabunc: Bagaimana dengan itu? Itu tercantum dalam paragraf terakhir dari jawaban saya.
Demian Brecht
@ Demian Brecht, tidak, sebenarnya dalam variabel paragraf terakhir dipanggil foodan fungsi disebutMY_function
shabunc
@shabunc: Nama tidak masalah. Yang penting adalah nilai dalam callstack. Sebagai contoh, [NAMESPACE] _ [nama fn] adalah konvensi yang digunakan oleh Mozilla. Nama itu sendiri tidak masalah asalkan konvensi Anda konsisten di seluruh proyek Anda.
Demian Brecht
13

ekspresi fungsi:

//someFunction(); //wouldn't work when uncommented
var someFunction = function(){ alert('yay'); };

Ekspresi func dalam hal ini adalah anonim tetapi ditugaskan ke var untuk referensi. Ini berbeda dari pernyataan fungsi yang berlabel dengan cara berikut:

  • tidak dapat diangkat (dipanggil sebelum ditentukan)
  • new someFunction().constructor.name === 'someFunction';//false contoh tidak mendapatkan nama var untuk constructor.name karena referensi ke fungsi ditugaskan ke var tetapi var, bukan fungsi, terkait dengan nama var

Dalam pernyataan fungsi berlabel:

//someFunction(); //works when uncommented
function someFunction(){ alert('yay'); }
  • mengangkat karya
  • new someFunction().constructor.name === 'someFunction'; //true nama diikat langsung ke fungsi.

Secara umum sebenarnya tidak ada alasan bagus untuk melakukan ekspresi ke var kecuali jika Anda ingin panggilan gagal jika ada yang bergerak atau Anda mendefinisikan / menetapkan metode dalam satu baris. Saya benar-benar menemukan mengangkat berguna untuk mengatur objek dengan func internal dan definisi metode di bagian bawah sehingga saya bisa sampai ke perilaku aktual objek dan melakukan definisi metode publik satu baris (dengan hanya menetapkan funcs this.dengan nama yang sama) semuanya dalam satu tempat untuk kemudahan referensi. Anda harus selalu mencoba menggunakan pernyataan berlabel untuk konstruktor, IMO, sehingga Anda dapat mengidentifikasi 'tipe' objek melalui konstruktornya.

Erik Reppen
sumber
8

Contoh pertama Anda adalah ekspresi sedangkan contoh kedua adalah pernyataan . Mendefinisikan fungsi sebagai ekspresi memungkinkan lebih banyak fleksibilitas di mana definisi dapat terjadi, apa yang dapat Anda tetapkan, bahwa Anda dapat meneruskannya sebagai parameter, dll ...

Sebagai contoh:

SomeThing('abc', function(a,b) {return a*b;});

vs ...

function tmp(a,b) { 
    return a*b;
}

SomeThing('abc', tmp);

Contoh yang lebih kompleks akan menjadi sangat rumit tanpa sintaks ekspresi fungsi.

Lihatlah https://stackoverflow.com/questions/111102/how-do-javascript-closures-work

gahooa
sumber
4

Perbedaan praktis utama adalah mengangkat. Sebagai contoh:

foo(); // alerts 'hello'
function foo() {alert('hello');}

vs.

foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}

Juga, ini adalah perilaku yang tidak terdefinisi

function foo(){
  if (true) {
    function bar(){}
  }
  bar();
}

sementara ini ok.

function foo(){
  if (true) {
    var bar = function(){}
  }
  bar();
}
Austin
sumber
7
Sama sekali tidak ada yang salah dengan mendefinisikan fungsi di dalam fungsi di JS. Tidak banyak tempat Anda tidak dapat mendefinisikan fungsi di JS.
Erik Reppen
2
@ErikReppen Anda pasti tidak dapat menggunakan deklarasi fungsi di dalam blok non-fungsi (seperti dalam pernyataan if). Sepertinya saya tidak dapat menemukan di mana saya membaca mereka tidak dapat digunakan dalam fungsi lain.
Austin
@Austin Tidak ada yang salah dengan definisi fungsi di dalam ifpernyataan!
Tim
@ Austin: Mungkin Anda membacanya di w3schools? ;)
Demian Brecht
2
Ekspresi fungsi @ErikReppen dapat digunakan di mana saja. Deklarasi fungsi tidak bisa. Lihat stackoverflow.com/questions/10069204/…
Austin