Pertanyaan Asli:
JSHint mengeluh ketika JavaScript saya memanggil fungsi yang didefinisikan jauh di bagian bawah halaman daripada memanggilnya. Namun, halaman saya adalah untuk permainan, dan tidak ada fungsi yang dipanggil sampai semuanya diunduh. Jadi mengapa fungsi order muncul di kode saya penting?
EDIT: Saya pikir saya mungkin telah menemukan jawabannya.
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Saya mengerang di dalam. Sepertinya saya perlu menghabiskan satu hari lagi untuk memesan enam ribu baris kode. Kurva belajar dengan javascript tidak curam sama sekali, tapi sangat luuuuuuuuuuuuuuuuuuuuu
javascript
function
jslint
jshint
Chris Tolworthy
sumber
sumber
Jawaban:
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_CheatsheetPerilaku aneh ini bergantung pada
Berikut beberapa contohnya.
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 sepertivar name = function() {}
(atau fungsi anonim yang ditugaskan untuk mengembalikan, hal-hal seperti itu), itu ekspresi fungsi .Pertama, mari kita lihat bagaimana variabel ditangani:
Sekarang, bagaimana deklarasi fungsi ditangani:
The
var
pernyataan "melempar" yang penciptaan darifoo
ke puncak, tetapi tidak menetapkan nilai untuk itu belum. Deklarasi fungsi muncul di baris berikutnya, dan akhirnya sebuah nilai ditetapkan kefoo
.Dan bagaimana dengan ini?
Hanya deklarasi dari
foo
dipindahkan ke atas. Penugasan dilakukan hanya setelah panggilan kebar
dilakukan, di mana sebelum semua pengangkatan terjadi.Dan akhirnya, untuk ringkasnya:
Sekarang, bagaimana dengan ekspresi fungsi ?
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.
Seperti yang telah kita lihat sebelumnya, hanya pembuatan dari
foo
yang diangkat, tugas datang di tempat ia muncul di kode "asli" (tidak dikerek). Ketikabar
dipanggil, itu sebelumfoo
diberi nilai, jadifoo === undefined
. Sekarang di dalam function-body daribar
, seolah-olah Anda sedang melakukanundefined()
, yang membuat kesalahan.sumber
Alasan utamanya mungkin karena JSLint hanya melakukan satu penyampaian pada file sehingga tidak tahu Anda akan mendefinisikan fungsi seperti itu.
Jika Anda menggunakan sintaks pernyataan fungsi
Sebenarnya tidak ada perbedaan sama sekali di mana Anda mendeklarasikan fungsi (itu selalu berperilaku seolah-olah deklarasi ada di awal).
Di sisi lain, jika fungsi Anda disetel seperti variabel biasa
Anda harus menjamin Anda tidak akan memanggilnya sebelum inisialisasi (ini sebenarnya bisa menjadi sumber bug).
Karena menyusun ulang banyak kode itu rumit dan bisa menjadi sumber bug itu sendiri, saya sarankan Anda mencari solusinya. Saya cukup yakin Anda bisa memberi tahu JSLint nama variabel global sebelumnya sehingga tidak mengeluh tentang hal-hal yang tidak dideklarasikan.
Beri komentar di awal file
Atau Anda dapat menggunakan kotak teks di sana untuk itu. (Saya juga berpikir Anda bisa meneruskan ini dalam argumen ke fungsi jslint batin jika Anda bisa ikut campur dengannya.)
sumber
Ada terlalu banyak orang yang mendorong aturan sewenang-wenang tentang bagaimana JavaScript harus ditulis. Kebanyakan peraturan adalah omong kosong.
Pengangkatan fungsi adalah fitur dalam JavaScript karena ini adalah ide yang bagus.
Jika Anda memiliki fungsi internal yang sering kali merupakan kegunaan fungsi dalam, menambahkannya ke awal fungsi luar adalah gaya penulisan kode yang dapat diterima, tetapi ada kekurangannya yaitu Anda harus membaca detailnya untuk mendapatkan apa fungsi luar tidak.
Anda harus tetap berpegang pada satu prinsip di seluruh basis kode Anda, baik menempatkan fungsi pribadi terlebih dahulu atau terakhir dalam modul atau fungsi Anda. JSHint bagus untuk menegakkan konsistensi, tetapi Anda harus SEBENARNYA menyesuaikan .jshintrc agar sesuai dengan kebutuhan Anda, TIDAK menyesuaikan kode sumber Anda dengan konsep pengkodean aneh orang lain.
Salah satu gaya pengkodean yang mungkin Anda lihat di alam liar harus Anda hindari karena tidak memberi Anda keuntungan dan hanya kemungkinan kesulitan refactoring:
Inilah fungsi hoisting yang harus dihindari. Pelajari saja bahasanya dan manfaatkan kekuatannya.
sumber
Hanya deklarasi fungsi yang diangkat, bukan ekspresi fungsi (penugasan).
sumber