Buku “JavaScript Ekspresif. Pemrograman web modern. Edisi ke-3

gambar Hai, habrozhiteli! Buku ini akan memungkinkan Anda untuk menyelam jauh ke dalam topik, belajar cara menulis kode yang indah dan efektif. Anda akan belajar tentang fungsi sintaks, panah dan asinkron, iterator, string pola, dan ruang lingkup blok.

Marein Haverbeke - praktisi. Dapatkan pengalaman dan belajar bahasa melalui banyak contoh melalui latihan dan proyek pelatihan. Pertama, Anda akan menjadi terbiasa dengan struktur bahasa JavaScript, mengelola struktur, fungsi dan struktur data, kemudian mempelajari penanganan kesalahan dan perbaikan bug, modularitas dan pemrograman asinkron, dan kemudian beralih ke pemrograman browser.

Tinjau buku ini


Buku ini dibagi menjadi tiga bagian besar. 12 bab pertama membahas bahasa JavaScript. Tujuh bab berikutnya adalah tentang browser dan bagaimana JavaScript digunakan untuk memprogram mereka. Akhirnya, dua bab dikhususkan untuk Node.js, lingkungan pemrograman JavaScript lainnya.

Sepanjang buku ini Anda akan bertemu lima bab proyek yang menggambarkan contoh program yang lebih besar sehingga Anda dapat merasakan cita rasa pemrograman yang sebenarnya. Sesuai urutan penampilan mereka, kami akan berupaya membuat robot pengiriman, bahasa pemrograman, platform game, editor grafis raster, dan situs dinamis.

Bagian bahasa buku dimulai dengan empat bab yang akan memperkenalkan Anda pada struktur dasar bahasa JavaScript. Anda akan belajar tentang struktur kontrol (seperti kata kunci sementara, yang sudah Anda lihat dalam pendahuluan), fungsi (menulis blok bangunan Anda sendiri), dan struktur data. Setelah itu, Anda dapat menulis program yang paling sederhana. Lebih lanjut, bab 5 dan 6 menjelaskan cara menggunakan fungsi dan objek untuk menulis kode yang lebih abstrak dan mengontrol kerumitannya.

Setelah bab dari proyek pertama, bagian bahasa buku akan dilanjutkan - bab-bab berikut ditujukan untuk mendeteksi dan memperbaiki kesalahan, ekspresi reguler (alat penting untuk bekerja dengan teks), modularitas (pertahanan lain terhadap kompleksitas) dan pemrograman asinkron (bekerja dengan peristiwa yang berlangsung selama beberapa waktu). Bagian pertama dari buku ini diselesaikan oleh bab dari draft kedua.

Bagian kedua, bab 13 hingga 19, menjelaskan alat yang dapat diakses oleh browser yang mengaktifkan JavaScript. Anda akan belajar cara menampilkan elemen di layar (bab 14 dan 17), merespons input pengguna (bab 15) dan membagikannya melalui jaringan (bab 18). Bagian ini juga berisi dua bab proyek.

Setelah itu, Node.js dijelaskan di bab 20, dan situs kecil dibuat di bab 21 menggunakan alat yang ditentukan.

Kutipan. Penjumlahan dengan mengurangi


Hal umum lain yang sering dilakukan dengan array adalah menghitung nilai tunggal berdasarkan pada mereka. Kasus khusus dari ini adalah contoh yang telah kita gunakan dengan penjumlahan satu set angka. Contoh lain adalah menemukan font yang mengandung karakter terbanyak.

Operasi tingkat tinggi yang menerapkan pola ini disebut singkatan (kadang-kadang juga disebut konvolusi). Operasi ini membangun nilai dengan berulang kali mendapatkan satu elemen dari array dan menggabungkannya dengan nilai saat ini. Saat menjumlahkan angka, kita mulai dari nol dan kemudian menambahkan setiap elemen berikutnya ke penjumlahan.

Parameter dari fungsi pengurangan, selain array, adalah fungsi menggabungkan dan nilai awal. Fungsi ini sedikit lebih rumit daripada filter dan peta, jadi perhatikan lebih dekat:

function reduce(array, combine, start) { let current = start; for (let element of array) { current = combine(current, element); } return current; } console.log(reduce([1, 2, 3, 4], (a, b) => a + b, 0)); // → 10 

Metode standar untuk bekerja dengan array pengurangan, yang, tentu saja, sesuai dengan fungsi ini, memiliki kenyamanan tambahan. Jika array berisi setidaknya satu elemen, Anda bisa menghilangkan argumen awal. Metode memilih elemen pertama array sebagai nilai awal dan mulai reduksi dari elemen kedua.

 console.log([1, 2, 3, 4].reduce((a, b) => a + b)); // → 10 

Untuk menggunakan perkecil (dua kali) untuk menemukan font dengan karakter terbanyak, kita dapat menulis sesuatu seperti ini:

 function characterCount(script) { return script.ranges.reduce((count, [from, to]) => { return count + (to — from); }, 0); } console.log(SCRIPTS.reduce((a, b) => { return characterCount(a) < characterCount(b) ? b : a; })); // → {name: "Han", ...} 

Fungsi characterCount mengurangi rentang yang ditetapkan untuk font ini dengan menghitung jumlah ukurannya. Perhatikan penggunaan perusakan dalam daftar parameter fungsi reduksi. Kemudian panggilan kedua untuk mengurangi menggunakan hasil sebelumnya untuk menemukan font terbesar, berulang kali membandingkan dua font dan mengembalikan yang lebih besar.

Font Han memiliki lebih dari 89.000 karakter yang ditetapkan padanya dalam standar Unicode, menjadikannya sistem penulisan terbesar dalam kumpulan data kami. Han adalah font yang kadang-kadang digunakan untuk teks berbahasa Mandarin, Jepang, dan Korea. Bahasa mereka memiliki banyak karakter umum, meskipun mereka ditulis secara berbeda. Konsorsium Unicode (berlokasi di AS) memutuskan untuk mempertimbangkan karakter seperti itu sebagai sistem perekaman tunggal untuk menyimpan kode karakter. Ini disebut Unifikasi Han dan masih sangat mengganggu bagi sebagian orang.

Kompabilitas


Mari kita pikirkan: bagaimana kita dapat menulis ulang contoh sebelumnya (menemukan font terbesar) tanpa fungsi tingkat tinggi? Kode berikut tidak jauh lebih buruk.

 let biggest = null; for (let script of SCRIPTS) { if (biggest == null || characterCount(biggest) < characterCount(script)) { biggest = script; } } console.log(biggest); // → {name: "Han", ...} 

Beberapa binding tambahan muncul, dan program menjadi empat baris lebih panjang. Namun kode ini masih cukup jelas.

Fungsi tingkat tinggi mulai sangat berguna ketika Anda perlu menyusun operasi. Sebagai contoh, kami akan menulis kode yang menghitung tahun rata-rata pembuatan font bahasa mati dan hidup dalam kumpulan data.

 function average(array) { return array.reduce((a, b) => a + b) / array.length; } console.log(Math.round(average( SCRIPTS.filter(s => s.living).map(s => s.year)))); // → 1188 console.log(Math.round(average( SCRIPTS.filter(s => !s.living).map(s => s.year)))); // → 188 

Dengan demikian, skrip bahasa yang mati di Unicode rata-rata lebih tua dari skrip bahasa yang hidup.

Ini bukan statistik yang signifikan atau mengejutkan. Tapi Anda mudah-mudahan setuju bahwa kode yang digunakan untuk menghitungnya mudah dibaca. Ini dapat dibayangkan sebagai konveyor: kita mulai dengan menganalisis semua font, menyaring yang hidup (atau mati), mengambil tahun pembuatannya, menghitung nilai rata-rata dan melengkapi hasilnya.

Perhitungan ini juga dapat direpresentasikan sebagai satu siklus besar.

 let total = 0, count = 0; for (let script of SCRIPTS) { if (script.living) { total += script.year; count += 1; } } console.log(Math.round(total / count)); // → 1188 

Tetapi dalam kode ini lebih sulit untuk memahami apa dan bagaimana cara menghitungnya. Dan karena hasil antara tidak disajikan sebagai nilai yang konsisten, banyak pekerjaan yang harus dilakukan untuk memisahkan sesuatu seperti rata-rata menjadi fungsi yang terpisah.

Dalam hal apa yang sebenarnya dilakukan komputer, kedua pendekatan ini pada dasarnya berbeda. Yang pertama membuat array baru ketika filter dan peta dijalankan, sedangkan yang kedua hanya menghitung beberapa angka, melakukan lebih sedikit pekerjaan. Biasanya Anda dapat membeli opsi yang lebih mudah dibaca, tetapi jika Anda harus memproses array yang sangat besar dan melakukannya berkali-kali, gaya yang kurang abstrak dapat memberi Anda tambahan kecepatan.

Kode string dan karakter


Salah satu penggunaan set data adalah untuk menentukan font mana dari suatu teks yang diketikkan. Mari kita lihat program yang melakukan ini.

Ingatlah bahwa untuk setiap font terdapat array rentang kode karakter. Oleh karena itu, mengetahui kode karakter, kita dapat menggunakan fungsi berikut untuk menemukan font yang sesuai (jika ada):

 function characterScript(code) { for (let script of SCRIPTS) { if (script.ranges.some(([from, to]) => { return code >= from && code < to; })) { return script; } } return null; } console.log(characterScript(121)); // → {name: "Latin", ...} 

Beberapa metode adalah fungsi urutan yang lebih tinggi. Dibutuhkan fungsi tes dan melaporkan jika mengembalikan true untuk elemen array apa pun.

Tetapi bagaimana kita mendapatkan kode karakter sebagai string?

Dalam Bab 1, saya menyebutkan bahwa dalam JavaScript, string direpresentasikan sebagai urutan angka 16-bit. Ini adalah unit kode yang disebut. Awalnya, diasumsikan bahwa dalam Unicode kode karakter akan ditempatkan di blok seperti itu (yang memberikan sedikit lebih dari 65.000 karakter). Ketika menjadi jelas bahwa ini tidak cukup, banyak mulai keberatan dengan kebutuhan untuk menggunakan lebih banyak memori untuk menyimpan satu karakter. Untuk mengatasi masalah ini, format UTF-16 yang digunakan dalam string JavaScript diciptakan. Di dalamnya, karakter yang paling umum menempati satu unit kode 16-bit, dan sisanya - dua unit kode.

Hari ini secara umum diterima bahwa UTF-16 adalah ide yang buruk. Tampaknya dibuat untuk menghasilkan kesalahan. Anda dapat dengan mudah menulis program yang unit kode dan karakternya satu dan sama. Dan jika bahasa ibu Anda tidak menggunakan karakter yang menempati dua unit kode, program ini akan berfungsi dengan baik. Tetapi, segera setelah seseorang mencoba menggunakan program semacam itu untuk alfabet yang kurang umum, misalnya, untuk karakter Cina, itu akan segera pecah. Untungnya, setelah munculnya emotikon, dua unit kode mulai digunakan di mana-mana untuk pengkodean karakter, dan beban penyelesaian masalah seperti itu didistribusikan lebih adil.

Sayangnya, operasi yang jelas dengan string JavaScript, seperti mendapatkan panjangnya melalui properti panjang dan mengakses konten mereka dengan tanda kurung siku, hanya berurusan dengan unit kode.

gambar

Metode JavaScript charCodeAt tidak mengembalikan kode karakter lengkap, tetapi unit kode. Metode codePointAt yang muncul kemudian mengembalikan karakter Unicode penuh. Jadi kita bisa menggunakan ini untuk mendapatkan karakter dari string. Namun argumen yang diteruskan ke codePointAt masih berupa indeks dalam urutan unit kode. Jadi, untuk mengulangi semua karakter dalam string, kita masih perlu menyelesaikan pertanyaan apakah satu atau dua unit kode menempati karakter.

Pada bab sebelumnya, saya menyebutkan bahwa for / of loop juga dapat digunakan untuk string. Seperti codePointAt, jenis loop ini muncul pada saat programmer jelas menyadari masalah UTF-16. Ketika Anda menerapkan loop ini ke string, itu memberikan karakter nyata, bukan unit kode.

gambar

Jika Anda memiliki karakter (yang merupakan string dari satu atau dua unit kode), maka untuk mendapatkan kodenya, Anda dapat menggunakan codePointAt (0).

Pengenalan teks


Kami memiliki fungsi characterScript dan cara untuk menghitung dengan benar karakter dalam satu lingkaran. Langkah selanjutnya adalah menghitung jumlah karakter yang dimiliki masing-masing font. Di sini kita membutuhkan abstraksi penghitungan:

 function countBy(items, groupName) { let counts = []; for (let item of items) { let name = groupName(item); let known = counts.findIndex(c => c.name == name); if (known == -1) { counts.push({name, count: 1}); } else { counts[known].count++; } } return counts; } console.log(countBy([1, 2, 3, 4, 5], n => n > 2)); // → [{name: false, count: 2}, {name: true, count: 3}] 

Fungsi countBy menerima koleksi (semua yang bisa diurutkan dalam for / of loop) dan fungsi yang menghitung nama grup untuk elemen yang diberikan. Fungsi countBy mengembalikan array objek, yang masing-masing berisi nama grup dan jumlah elemen yang ditemukan untuk itu.

Fungsi ini menggunakan metode lain untuk bekerja dengan array - findIndex. Metode ini agak mirip dengan indexOf, tetapi alih-alih mencari nilai tertentu, ia menemukan nilai pertama yang mengembalikan fungsi yang diberikan benar. Jika item tidak ditemukan, findIndex, seperti indexOf, mengembalikan -1.

Dengan menggunakan countBy, kita bisa menulis fungsi yang memberi tahu font mana yang digunakan dalam teks ini.

gambar

Fungsi pertama menghitung karakter dengan nama font, menggunakan characterScript untuk memberi mereka nama, dan mengembalikan string "tidak ada" untuk karakter yang bukan milik font apa pun. Filter panggilan menghapus entri "tidak ada" dari array yang dihasilkan, karena kami tidak tertarik dengan karakter ini.

Untuk dapat menghitung persentase, pertama-tama kita perlu mendapatkan jumlah total karakter yang dimiliki font yang dapat kita hitung menggunakan metode pengurangan. Jika tidak ada karakter yang ditemukan, maka fungsi mengembalikan string tertentu. Jika tidak, itu mengubah hasil penghitungan menjadi string yang dapat dibaca menggunakan peta, dan kemudian menggabungkannya menggunakan gabungan.

Ringkasan


Kemampuan untuk memberikan nilai fungsional ke fungsi lain adalah aspek yang sangat berguna dari JavaScript. Ini memungkinkan Anda untuk membuat fungsi yang mensimulasikan perhitungan dengan spasi. Selanjutnya, ketika memanggil fungsi-fungsi tersebut dalam kode, "celah" ini diisi dengan nilai-nilai fungsional.

Untuk array, ada sejumlah metode tingkat tinggi yang berguna. Metode forEach dapat digunakan untuk mengulang elemen-elemen dari sebuah array. Metode filter mengembalikan array baru yang hanya mengandung elemen yang memenuhi kondisi fungsi predikatif. Konversi array dengan mengeksekusi fungsi untuk setiap elemen dilakukan dengan menggunakan peta. Untuk menggabungkan semua elemen array ke dalam satu nilai, Anda bisa menggunakan pengurangan. Beberapa metode memeriksa apakah ada elemen yang cocok dengan fungsi predikatif yang diberikan. Akhirnya, metode findIndex menemukan posisi elemen pertama yang cocok dengan predikat.

»Informasi lebih lanjut tentang buku ini dapat ditemukan di situs web penerbit
» Isi
» Kutipan

Kupon diskon 25% untuk penjaja - JavaScript
Setelah pembayaran versi kertas buku, sebuah buku elektronik dikirim melalui email.

Source: https://habr.com/ru/post/id463465/


All Articles