Rumah > Artikel > hujung hadapan web > Menyahmistikan JavaScript: Memahami Konteks Pelaksanaan, Pengangkatan dan Penukaran Jenis
JavaScript mungkin kelihatan mudah pada permukaan, tetapi di bawah hud, terdapat banyak perkara yang berlaku. Hari ini, kami akan meneroka beberapa konsep penting seperti konteks pelaksanaan, angkat, jenis data primitif lwn bukan primitif dan penukaran jenis. Ini penting untuk difahami jika anda ingin menulis kod yang lebih baik dan bebas pepijat.
Konteks Pelaksanaan Global dan Persekitaran Leksikal
Apabila anda menjalankan fail JavaScript dalam penyemak imbas, kod tersebut akan dilaksanakan baris demi baris dalam timbunan panggilan. Walau bagaimanapun, sebelum mana-mana kod anda dijalankan, konteks pelaksanaan global dibuat. Konteks ini menyediakan objek ini dan tetingkap. Dalam Node.js, tetingkap yang setara adalah global dan jika anda membandingkan kedua-duanya, anda akan mendapati tetingkap itu === pulangan global benar.
Setiap kali anda memanggil fungsi, persekitaran leksikal baharu dicipta. Konteks pelaksanaan global adalah yang pertama dibuat, dan semua fungsi yang ditakrifkan di dalamnya boleh mengakses pembolehubahnya. Beginilah cara rantai skop JavaScript berfungsi — anda boleh mengakses pembolehubah dalam skop luar (global) dari dalam fungsi.
Pengangkat: Pembolehubah dan Fungsi
JavaScript mempunyai mekanisme yang dipanggil angkat, di mana pembolehubah dan fungsi "dialihkan" ke bahagian atas skop mereka semasa penyusunan. Begini cara ia berfungsi:
Pembolehubah: Pembolehubah yang diisytiharkan dengan var dinaikkan sebahagiannya, bermakna anda boleh merujuknya sebelum ia dimulakan, tetapi nilainya tidak akan ditentukan sehingga baris di mana ia dimulakan dicapai.
Fungsi: Fungsi yang diisytiharkan dengan sintaks pengisytiharan fungsi dinaikkan sepenuhnya, bermakna anda boleh memanggil fungsi itu walaupun sebelum pengisytiharannya dalam kod.
Contoh:
console.log(a); // undefined var a = 5; console.log(b); // Error: b is not defined let b = 10; hoistedFunction(); // Works! function hoistedFunction() { console.log('This function is hoisted!'); } notHoistedFunction(); // Error: notHoistedFunction is not a function var notHoistedFunction = function() { console.log('This function is not hoisted!'); }
Seperti yang anda lihat, let dan const tidak dinaikkan seperti var, dan ungkapan fungsi (seperti notHoistedFunction) hanya ditakrifkan pada masa jalan.
Jenis Primitif lwn. Bukan Primitif
JavaScript mempunyai dua jenis data: primitif dan bukan primitif.
Jenis primitif termasuk rentetan, nombor, boolean, undefined, null, simbol dan bigint. Ini tidak boleh diubah, bermakna nilai mereka tidak boleh diubah. Contohnya:
let x = 'hello'; x[0] = 'H'; // This won’t change the string, it stays 'hello'
Jenis bukan primitif ialah objek, tatasusunan dan fungsi. Ini boleh ubah, dan nilainya boleh diubah kerana ia diluluskan melalui rujukan. Contohnya:
let obj1 = { name: 'John' }; let obj2 = obj1; // Both obj1 and obj2 now reference the same object obj2.name = 'Doe'; console.log(obj1.name); // Outputs: Doe
Untuk mengelak daripada mengubah suai objek asal, anda boleh mencipta salinan cetek menggunakan Object.assign() atau operator spread (...). Untuk salinan dalam, yang menyalin objek bersarang, gunakan JSON.parse() dan JSON.stringify().
Contoh Coretan Kod: Salinan Cetek lwn Salinan Dalam
// Shallow copy example let obj1 = { name: 'John', details: { age: 30 } }; let obj2 = { ...obj1 }; // Shallow copy obj2.details.age = 40; console.log(obj1.details.age); // Output: 40 (Shallow copy affects the original) // Deep copy example let obj3 = JSON.parse(JSON.stringify(obj1)); // Deep copy obj3.details.age = 50; console.log(obj1.details.age); // Output: 40 (Deep copy doesn’t affect the original)
Penukaran Jenis dan Perbandingan
JavaScript ialah bahasa yang ditaip secara dinamik, bermakna anda tidak perlu menentukan jenis pembolehubah secara eksplisit. Walau bagaimanapun, ini kadangkala boleh menyebabkan tingkah laku yang tidak dijangka, terutamanya apabila menggunakan pengendali perbandingan.
Sentiasa lebih suka menggunakan triple equals (===) berbanding double equals (==) untuk mengelakkan jenis paksaan. Contohnya:
console.log(0 == '0'); // true (type coercion happens) console.log(0 === '0'); // false (no type coercion)
Untuk kes khas, seperti membandingkan NaN, gunakan Object.is() kerana NaN === NaN mengembalikan palsu.
console.log(NaN === NaN); // false console.log(Object.is(NaN, NaN)); // true
Waktu Jalan JavaScript dan Node.js
JavaScript berjalan pada satu-benang, masa jalan segerak, yang bermaksud ia hanya boleh melaksanakan satu tugas pada satu masa. Ini mungkin kelihatan terhad, tetapi JavaScript mengendalikan tugas tak segerak dengan cekap menggunakan API Web dan baris gilir panggil balik. Begini cara ia berfungsi:
Apabila JavaScript menghadapi tugas async (seperti setTimeout atau permintaan HTTP), ia menghantar tugasan ke API Web.
Tindanan panggilan terus melaksanakan kod yang tinggal.
Setelah tugas async selesai, ia ditambahkan pada baris gilir panggil balik dan akan dilaksanakan apabila tindanan panggilan kosong.
Node.js memanjangkan masa jalan ini ke bahagian pelayan, menggunakan enjin V8 dan sistem I/O tanpa sekatan yang dikuasakan oleh libuv. Node.js memperkenalkan idea gelung acara berbenang tunggal yang boleh mengendalikan berbilang permintaan tanpa menyekat operasi lain.
Dengan memahami cara JavaScript mengendalikan konteks pelaksanaan, pengangkatan, penukaran jenis dan tugas tak segerak, anda akan dapat menulis kod yang lebih bersih dan cekap. Dengan sifat dinamik JavaScript, alatan seperti TypeScript boleh membantu anda mengelakkan perangkap biasa dengan menyediakan semakan jenis statik yang menjadikan pengeluaran kod anda sedia.
Atas ialah kandungan terperinci Menyahmistikan JavaScript: Memahami Konteks Pelaksanaan, Pengangkatan dan Penukaran Jenis. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!