tl; dr Jika Anda tidak menelepon apa pun sampai semuanya dimuat, Anda akan baik-baik saja.
Edit: Untuk gambaran umum yang juga mencakup beberapa deklarasi ES6 ( let
, const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet
Perilaku aneh ini bergantung pada
- Bagaimana Anda mendefinisikan fungsi dan
- Saat Anda menelepon mereka.
Berikut beberapa contohnya.
bar(); //This won't throw an error
function bar() {}
foo(); //This will throw an error
var foo = function() {}
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
bar();
function bar() {
foo(); //This _won't_ throw an error
}
function foo() {}
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
Ini karena sesuatu yang disebut mengangkat !
Ada dua cara untuk mendefinisikan fungsi: Deklarasi fungsi dan ekspresi fungsi . Perbedaannya menjengkelkan dan menit, jadi anggap saja hal ini sedikit salah: Jika Anda menulisnya seperti function name() {}
, itu adalah deklarasi , dan ketika Anda menulisnya seperti var name = function() {}
(atau fungsi anonim yang ditugaskan untuk mengembalikan, hal-hal seperti itu), itu ekspresi fungsi .
Pertama, mari kita lihat bagaimana variabel ditangani:
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
Sekarang, bagaimana deklarasi fungsi ditangani:
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It's now at the top
function bar() {}
foo = 42;
The var
pernyataan "melempar" yang penciptaan dari foo
ke puncak, tetapi tidak menetapkan nilai untuk itu belum. Deklarasi fungsi muncul di baris berikutnya, dan akhirnya sebuah nilai ditetapkan ke foo
.
Dan bagaimana dengan ini?
bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
Hanya deklarasi dari foo
dipindahkan ke atas. Penugasan dilakukan hanya setelah panggilan ke bar
dilakukan, di mana sebelum semua pengangkatan terjadi.
Dan akhirnya, untuk ringkasnya:
bar();
function bar() {}
//turns to
function bar() {}
bar();
Sekarang, bagaimana dengan ekspresi fungsi ?
var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
Sama seperti variabel biasa, pertama foo
adalah dideklarasikan pada titik tertinggi dari ruang lingkup, maka ditugaskan nilai.
Mari kita lihat mengapa contoh kedua memunculkan kesalahan.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
Seperti yang telah kita lihat sebelumnya, hanya pembuatan dari foo
yang diangkat, tugas datang di tempat ia muncul di kode "asli" (tidak dikerek). Ketika bar
dipanggil, itu sebelum foo
diberi nilai, jadi foo === undefined
. Sekarang di dalam function-body dari bar
, seolah-olah Anda sedang melakukan undefined()
, yang membuat kesalahan.