Saya menulis skrip berikut hanya untuk melihat apa yang terjadi ketika variabel dan fungsi yang memiliki fungsi yang ditugaskan padanya memiliki nama yang bentrok:
var f = function() {
console.log("Me original.");
}
function f() {
console.log("Me duplicate.");
}
f();
Output yang saya dapatkan adalah "Saya asli." Mengapa fungsi lainnya tidak dipanggil?
Juga, jika saya mengubah tugas awal saya menjadi var f = new function() {
, saya mendapatkan "Saya asli", diikuti dengan pepatah TypeError object is not a function
. Bisakah seseorang menjelaskan?
javascript
function
ankush981
sumber
sumber
Jawaban:
Deklarasi fungsi diangkat (dipindahkan ke atas) di JavaScript. Meskipun salah dalam hal urutan penguraian, kode yang Anda miliki secara semantik sama dengan yang berikut karena deklarasi fungsi diangkat:
Yang pada gilirannya, dengan pengecualian nama fungsinya sama dengan:
Yang pada gilirannya, karena pengangkat variabel adalah sama dengan:
Yang menjelaskan apa yang Anda dapatkan, Anda mengganti fungsinya. Secara lebih umum, beberapa
var
deklarasi diperbolehkan dalam JavaScript -var x = 3; var x = 5
sangat legal. Dalam standar ECMAScript 6 baru,let
pernyataan melarang ini.Artikel oleh @kangax ini melakukan pekerjaan yang luar biasa dalam mendemistifikasi fungsi di javascript
sumber
function f()
untukvar f = function()
yang banyak? Apakah nama hoisting dan fungsi benar-benar satu - satunya perbedaan?f
diangkat, dan"Me Original"
versi baru saja diangkat kemudian , masing-masing dipindahkan ke atas tetapi dalam urutan yang sama. Saya hanya ingin menambahkan bahwa secara umum, Anda tidak boleh memberi nama beberapa fungsi dengan cara yang sama :)var
menggunakan nama yang sama dua kali dalam lingkup yang sama.Jika sepertinya tidak ada yang menjawab pertanyaan tindak lanjut Anda, maka saya akan menjawabnya di sini, meskipun Anda biasanya harus mengajukan pertanyaan lanjutan sebagai pertanyaan terpisah.
Anda bertanya mengapa ini:
mencetak "Saya asli." dan kemudian terjadi kesalahan.
Apa yang terjadi di sini adalah
new
penyebab fungsi digunakan sebagai konstruktor. Jadi ini setara dengan berikut ini:Dan berkat fungsi hoisting yang dijelaskan Benjamin, hal di atas pada dasarnya setara dengan ini:
Ekspresi ini:
menyebabkan objek baru dibangun dan ditetapkan
f
, menggunakan fungsi anonim sebagai konstruktor. "Saya asli." dicetak saat konstruktor dijalankan. Tapi objek yang dibangun itu sendiri bukanlah sebuah fungsi, jadi ketika ini akhirnya dijalankan:Anda mendapatkan kesalahan, karena
f
bukan fungsi.sumber
Maafkan saya jika ini adalah cara yang salah untuk mendekati menambahkan poin. Saya belum sering berada di sini, dan akan menerima arahan dan / atau kritik yang membangun.
Jawaban Benjamin menjawab pertanyaan OP dengan sangat baik, tetapi saya ingin menambahkan satu penyesuaian yang akan memberi kita tur lengkap tentang pengangkatan dan keanehannya.
Jika kita memulai kode asli dengan panggilan ke
f
, seperti:Outputnya kemudian akan menjadi:
Alasannya karena
var
danfunction
pernyataan dikibarkan dengan cara yang sedikit berbeda.Untuk
var
itu deklarasi dipindahkan ke bagian atas ruang lingkup saat ini *, tetapi setiap tugas tidak mengangkat. Sejauh nilai dari variabel yang dideklarasikan berjalan, itu tidak ditentukan sampai baris tugas asli tercapai.Untuk
function
pernyataan , baik deklarasi maupun definisi diangkat. Ekspresi fungsi , seperti yang digunakan dalamvar f = function() {...
konstruksi, tidak diangkat.Jadi setelah mengangkat, eksekusi seolah-olah kodenya adalah:
* Semua cakupan JavaScript adalah leksikal, atau fungsi, cakupan, tetapi sepertinya itu hanya akan membingungkan jika menggunakan kata f pada saat itu.
sumber