Hari ini, di bagian kedelapan dari terjemahan manual JavaScript, kami akan meninjau fitur bahasa yang muncul di dalamnya setelah rilis standar ES6. Dengan satu atau lain cara, kita telah menemukan banyak peluang ini sebelumnya, di suatu tempat memikirkannya secara lebih rinci, suatu tempat menerima begitu saja. Bagian panduan ini dimaksudkan, bersama dengan pengungkapan beberapa topik yang belum pernah kami sentuh sebelumnya, untuk merampingkan pengetahuan pengembang pemula di bidang JavaScript modern.
→
Bagian 1: program pertama, fitur bahasa, standar→
Bagian 2: gaya kode dan struktur program→
Bagian 3: variabel, tipe data, ekspresi, objek→
Bagian 4: fungsi→
Bagian 5: array dan loop→
Bagian 6: pengecualian, titik koma, literal wildcard→
Bagian 7: mode ketat, kata kunci ini, acara, modul, perhitungan matematis→
Bagian 8: Gambaran Umum Fitur ES6→
Bagian 9: Gambaran Umum Standar ES7, ES8, dan ES9
Tentang ES6
Standar ES6, yang akan lebih tepat untuk memanggil ES2015 atau ECMAScript 2015 (ini adalah nama resminya, meskipun semua orang menyebutnya ES6), muncul 4 tahun setelah rilis standar sebelumnya - ES5.1. Butuh sekitar sepuluh tahun untuk mengembangkan semua yang masuk ke standar ES5.1. Saat ini, segala sesuatu yang muncul dalam standar ini telah menjadi alat biasa dari pengembang JS. Perlu dicatat bahwa ES6 membuat perubahan besar pada bahasa (dengan tetap mempertahankan kompatibilitas dengan versi sebelumnya). Untuk menghargai besarnya perubahan ini, dapat dicatat bahwa ukuran dokumen yang menggambarkan standar ES5 adalah sekitar 250 halaman, dan standar ES6 dijelaskan dalam dokumen yang sudah memiliki sekitar 600 halaman.
Daftar inovasi paling penting dari standar ES2015 dapat mencakup yang berikut:
- Fungsi panah
- Janji
- Generator
- Kata kunci
let
dan const
- Kelas
- Modul
- Template Literal Support
- Dukungan untuk parameter fungsi default
- Operator yang tersebar
- Tugas Merusak
- Meningkatkan Literal Obyek
for...of
loop- Dukungan untuk
Map
dan Set
struktur data
Pertimbangkan kemungkinan ini.
Fungsi panah
Fungsi panah telah mengubah tampilan dan nuansa kode JavaScript. Dalam hal tampilan, penggunaannya membuat deklarasi fungsi lebih pendek dan lebih mudah. Berikut adalah deklarasi fungsi reguler.
const foo = function foo() {
Tetapi fungsi panah yang hampir sama (walaupun tidak sepenuhnya mirip dengan yang di atas).
const foo = () => {
Jika tubuh fungsi panah hanya terdiri dari satu baris, yang hasilnya harus dikembalikan dari fungsi ini, maka itu ditulis lebih pendek.
const foo = () => doSomething()
Jika fungsi panah hanya mengambil satu parameter, Anda dapat menuliskannya sebagai berikut.
const foo = param => doSomething(param)
Perlu dicatat bahwa dengan munculnya fungsi panah, fungsi biasa belum hilang, mereka masih dapat digunakan dalam kode, mereka bekerja dengan cara yang sama seperti sebelumnya.
Fitur Kata Kunci Ini dalam Fungsi Panah
Fungsi panah tidak memiliki nilai
this
sendiri, mereka mewarisinya dari konteks eksekusi.
Ini memperbaiki masalah, yang, ketika menggunakan fungsi biasa, perlu menggunakan konstruksi seperti
var that = this
untuk mempertahankan konteks. Namun, seperti yang ditunjukkan pada bagian sebelumnya dari panduan ini, perubahan ini sangat memengaruhi fitur bekerja dengan fungsi panah dan cakupan aplikasi mereka.
Janji
Janji memungkinkan Anda untuk menyingkirkan masalah terkenal yang disebut "panggilan balik neraka", meskipun penggunaannya menyiratkan penggunaan struktur yang agak rumit. Masalah ini diselesaikan dalam standar ES2017 dengan munculnya
async/await
konstruksi, yang didasarkan pada janji.
Pengembang JavaScript menggunakan janji sebelum standar ES2015, menggunakan berbagai pustaka untuk ini (misalnya - jQuery, q, deferred.js, sumpah). Ini menunjukkan pentingnya dan relevansi mekanisme ini. Perpustakaan yang berbeda menerapkannya dengan cara yang berbeda, munculnya standar di bidang ini dapat dianggap sebagai fakta yang sangat positif.
Berikut adalah kode yang ditulis menggunakan fungsi callback (panggilan balik).
setTimeout(function() { console.log('I promised to run after 1s') setTimeout(function() { console.log('I promised to run after 2s') }, 1000) }, 1000)
Menggunakan janji, ini dapat ditulis ulang sebagai berikut.
const wait = () => new Promise((resolve, reject) => { setTimeout(resolve, 1000) }) wait().then(() => { console.log('I promised to run after 1s') return wait() }) .then(() => console.log('I promised to run after 2s'))
Generator
Generator adalah fungsi khusus yang dapat menjeda eksekusi mereka sendiri dan melanjutkannya. Ini memungkinkan kode lain dijalankan ketika generator dalam keadaan idle.
Generator memutuskan sendiri bahwa ia perlu menjeda dan mengizinkan kode lain, "menunggu" untuk gilirannya, untuk dieksekusi. Pada saat yang sama, generator memiliki kesempatan untuk melanjutkan eksekusi setelah operasi, yang hasilnya menunggu, selesai.
Semua ini dilakukan berkat satu
yield
kata kunci sederhana. Ketika kata kunci ini ditemukan di generator, eksekusinya dijeda.
Generator dapat berisi banyak baris dengan kata kunci ini, menjeda eksekusi sendiri beberapa kali. Generator dideklarasikan dengan menggunakan
*function
. Tanda bintang ini sebelum
function
kata tidak boleh diambil untuk sesuatu seperti operator penunjuk titik yang digunakan dalam bahasa seperti C, C ++ atau Go.
Generator menandai munculnya paradigma pemrograman JavaScript baru. Secara khusus, mereka memungkinkan pertukaran data dua arah antara generator dan kode lainnya, dan memungkinkan pembuatan loop
while
yang tidak akan "menggantung" program.
Pertimbangkan contoh yang menggambarkan fitur-fitur pengoperasian generator. Ini generatornya sendiri.
function *calculator(input) { var doubleThat = 2 * (yield (input / 2)) var another = yield (doubleThat) return (input * doubleThat * another) }
Dengan perintah ini kita menginisialisasi itu.
const calc = calculator(10)
Kemudian kita beralih ke iteratornya.
calc.next()
Perintah ini memulai iterator, mengembalikan objek seperti itu.
{ done: false value: 5 }
Di sini hal berikut terjadi. Kode menjalankan fungsi menggunakan nilai
input
diteruskan ke konstruktor generator. Kode generator dijalankan hingga kata kunci
yield
ditemukan di dalamnya. Pada titik ini, ia mengembalikan hasil dari membagi
input
dengan
2
, yang, karena
input
adalah
10
, memberikan angka
5
. Kami mendapatkan nomor ini berkat iterator, dan, bersamaan dengan itu, indikasi bahwa generator belum selesai (properti yang
done
pada objek yang dikembalikan oleh iterator disetel ke
false
), yaitu, fungsinya hanya ditangguhkan.
Kali berikutnya iterator dipanggil, kita meneruskan angka
7
ke generator.
calc.next(7)
Menanggapi hal ini, iterator mengembalikan objek berikutnya kepada kami.
{ done: false value: 14 }
Di sini, angka
7
digunakan untuk menghitung nilai
doubleThat
.
Sekilas, mungkin tampak bahwa
input / 2
kode adalah sesuatu seperti argumen untuk suatu fungsi, tetapi ini hanya nilai yang dikembalikan pada iterasi pertama. Di sini kita melewatkan nilai ini dan menggunakan nilai input baru
7
, mengalikannya dengan
2
. Setelah itu, kita sampai pada kata kunci
yield
kedua, sebagai hasilnya, nilai yang diperoleh pada iterasi kedua adalah
14
.
Pada iterasi berikutnya, yang merupakan yang terakhir, kami memberikan angka
100
ke generator.
calc.next(100)
Sebagai tanggapan, kami mendapatkan objek berikut.
{ done: true value: 14000 }
Iterasi selesai (kata kunci
yield
tidak lagi ditemukan dalam generator), hasil evaluasi ekspresi
(input * doubleThat * another)
dikembalikan dalam objek, yaitu -
10 * 14 * 100
dan indikasi penyelesaian iterator (
done: true
).
Kata kunci let dan const
JavaScript selalu menggunakan kata kunci
var
untuk mendeklarasikan variabel. Variabel semacam itu memiliki cakupan fungsional. Kata kunci
let
dan
const
, masing-masing, memungkinkan Anda untuk mendeklarasikan variabel dan konstanta yang memiliki cakupan blok.
Ini berarti bahwa, misalnya, variabel yang dideklarasikan menggunakan kata kunci
let
dalam satu loop, di dalam blok
if
, atau di dalam blok kode reguler yang dibatasi oleh kurung kurawal, tidak akan melampaui blok ini. Variabel yang dideklarasikan dengan
var
tidak disimpan dalam blok-blok seperti itu, menjadi tersedia dalam fungsi di tingkat yang dideklarasikan.
Kata kunci
const
berfungsi seperti
let
, tetapi dengan itu, konstanta yang tidak dapat diubah dinyatakan.
Dalam kode JS modern, kata kunci
var
jarang digunakan. Ini memberi jalan pada kata kunci
let
dan
const
. Pada saat yang sama, yang mungkin tampak tidak biasa, kata kunci
const
digunakan sangat luas hari ini, yang menunjukkan popularitas ide-ide kekebalan entitas dalam pemrograman modern.
Kelas
Ternyata JavaScript adalah satu-satunya bahasa yang sangat luas yang menggunakan model pewarisan prototipe. Pemrogram beralih ke JS dari bahasa yang menerapkan mekanisme pewarisan berbasis kelas merasa tidak nyaman dalam lingkungan seperti itu. Standar ES2015 memperkenalkan dukungan kelas dalam JavaScript. Ini pada dasarnya adalah "gula sintaksis" di sekitar mekanisme internal JS menggunakan prototipe. Namun, ini mempengaruhi bagaimana tepatnya aplikasi JS menulis.
Mekanisme pewarisan JavaScript sekarang terlihat seperti mekanisme serupa dalam bahasa berorientasi objek lainnya.
class Person { constructor(name) { this.name = name } hello() { return 'Hello, I am ' + this.name + '.' } } class Actor extends Person { hello() { return super.hello() + ' I am an actor.' } } var tomCruise = new Actor('Tom Cruise') console.log(tomCruise.hello())
Program ini menampilkan teks
Hello, I am Tom Cruise. I am an actor
ke konsol
Hello, I am Tom Cruise. I am an actor
Hello, I am Tom Cruise. I am an actor
.
Di kelas JS, variabel instan tidak dapat dideklarasikan, mereka harus diinisialisasi dalam konstruktor.
Konstruktor kelas
Kelas memiliki metode khusus,
constructor
, yang dipanggil ketika turunan kelas dibuat menggunakan kata kunci
new
.
▍ Kata kunci super
Kata kunci
super
memungkinkan Anda untuk mengakses kelas induk dari kelas turunan.
▍ Getters and setters
Pembuat untuk properti dapat diatur sebagai berikut.
class Person { get fullName() { return `${this.firstName} ${this.lastName}` } }
Setter dapat digambarkan seperti yang ditunjukkan di bawah ini.
class Person { set age(years) { this.theAge = years } }
Mereka bekerja dengan getter dan setter seolah-olah mereka bukan fungsi, tetapi properti benda biasa.
Modul
Sebelum standar ES2015, ada beberapa pendekatan yang bersaing untuk bekerja dengan modul. Secara khusus, kita berbicara tentang teknologi RequireJS dan CommonJS. Situasi ini menyebabkan ketidaksepakatan di komunitas pengembang JS.
Saat ini, berkat standarisasi modul di ES2015, situasinya secara bertahap menjadi normal.
▍ Impor modul
Modul diimpor menggunakan konstruk dari formulir
import...from...
Berikut ini beberapa contohnya.
import * as something from 'mymodule' import React from 'react' import { React, Component } from 'react' import React as MyLibrary from 'react'
▍ Ekspor modul
Mekanisme internal modul ditutup dari dunia luar, tetapi dari modul Anda dapat mengekspor semua yang dapat ditawarkan modul lain. Ini dilakukan dengan menggunakan kata kunci
export
.
export var foo = 2 export function bar() { }
▍ Templat literal
Templat literal adalah cara baru untuk menggambarkan string dalam JavaScript. Ini tampilannya.
const aString = `A string`
Selain itu, menggunakan sintaks literal templat memungkinkan Anda untuk menanamkan ekspresi dalam string dan menyisipkannya. Ini dilakukan dengan menggunakan konstruksi formulir
${a_variable}
. Berikut adalah contoh sederhana penggunaannya:
const v = 'test' const str = `something ${v}`
Berikut adalah contoh yang lebih rumit, yang menggambarkan kemampuan untuk mengevaluasi ekspresi apa pun dan mengganti hasilnya dalam string.
const str = `something ${1 + 2 + 3}` const str2 = `something ${foo() ? 'x' : 'y' }`
Berkat penggunaan templat literal, menjadi lebih mudah untuk mendeklarasikan string multi-line.
const str3 = `Hey this string is awesome!`
Bandingkan ini dengan apa yang harus Anda lakukan untuk menggambarkan string multi-line saat menggunakan fitur yang tersedia dalam bahasa sebelum ES2015.
var str = 'One\n' + 'Two\n' + 'Three'
Parameter Fungsi Default
Sekarang fungsi mendukung parameter yang digunakan secara default - jika argumen yang sesuai tidak diteruskan kepada mereka saat memanggil fungsi.
const foo = function(index = 0, testing = true) { } foo()
Operator yang tersebar
Operator spread (operator ekstensi) memungkinkan Anda untuk "memperluas" array, objek, atau string. Operator ini terlihat seperti tiga titik (
...
). Pertama, pertimbangkan dengan contoh array.
const a = [1, 2, 3]
Berikut cara membuat array baru berdasarkan array ini.
const b = [...a, 4, 5, 6]
Berikut cara membuat salinan array.
const c = [...a]
Operator ini juga bekerja dengan objek. Misalnya, inilah cara menggunakannya untuk mengkloning suatu objek.
const newObj = { ...oldObj }
Menerapkan operator spread ke string, Anda bisa mengonversinya menjadi array, yang masing-masing elemennya mengandung satu karakter dari string ini.
const hey = 'hey' const arrayized = [...hey]
Operator ini, selain varian aplikasi di atas, mudah digunakan ketika memanggil fungsi yang mengharapkan daftar argumen normal, memberikan mereka array dengan argumen ini.
const f = (foo, bar) => {} const a = [1, 2] f(...a)
Sebelumnya, ini dilakukan dengan menggunakan konstruksi dari bentuk
f.apply(null, a)
, tetapi kode seperti itu lebih sulit untuk ditulis dan kurang dapat dibaca.
Tugas Merusak
Teknik penugasan destruksi memungkinkan, misalnya, untuk mengambil objek, mengekstraksi beberapa nilai darinya dan menempatkannya dalam variabel atau konstanta bernama.
const person = { firstName: 'Tom', lastName: 'Cruise', actor: true, age: 54, } const {firstName: name, age} = person
Di sini, properti
firstName
dan
age
diambil dari objek. Properti
age
ditulis ke konstanta yang dideklarasikan dengan nama yang sama, dan properti
firstName
, setelah ekstraksi, jatuh ke
name
konstan.
Tugas yang merusak juga cocok untuk bekerja dengan array.
const a = [1,2,3,4,5] const [first, second, , , fifth] = a
Konstanta
first
,
second
dan
fifth
mendapatkan elemen pertama, kedua, dan kelima dari array.
Meningkatkan Literal Obyek
ES2015 telah sangat memperluas kemampuan untuk menggambarkan objek menggunakan literal objek.
▍ Penyederhanaan penyertaan variabel dalam objek
Sebelumnya, untuk menetapkan variabel ke properti objek, perlu menggunakan konstruksi berikut.
const something = 'y' const x = { something: something }
Sekarang hal yang sama dapat dilakukan seperti ini.
const something = 'y' const x = { something }
▍ Prototipe
Prototipe objek sekarang dapat diatur menggunakan konstruksi berikut.
const anObject = { y: 'y' } const x = { __proto__: anObject }
▍ Kata kunci super
Menggunakan kata kunci
super
, objek dapat mengakses objek prototipe. Misalnya, untuk memanggil metode mereka yang memiliki nama yang sama dengan metode objek ini sendiri.
const anObject = { y: 'y', test: () => 'zoo' } const x = { __proto__: anObject, test() { return super.test() + 'x' } } x.test()
▍ Nama properti yang dihitung
Nama properti yang dihitung terbentuk pada tahap pembuatan objek.
const x = { ['a' + '_' + 'b']: 'z' } x.a_b
Untuk ... dari loop
Pada 2009, dalam standar ES5,
forEach()
loop muncul. Ini adalah desain yang bermanfaat, kelemahannya adalah kenyataan bahwa siklus seperti itu sangat tidak nyaman untuk disela. Klasik
for
loop dalam situasi di mana Anda perlu menghentikan eksekusi loop sebelum selesai normal adalah pilihan yang jauh lebih tepat.
An
for...of
cycle telah muncul di ES2015, yang, di satu sisi, dibedakan oleh sintaksisnya yang ringkas dan kenyamanan
forEach
, dan di sisi lain, ia mendukung kemungkinan keluar awal dari siklus.
Berikut adalah beberapa contoh
for...of
loop.
Memetakan dan Mengatur Struktur Data
ES2015 memperkenalkan
Map
dan
Set
struktur data (serta versi "lemah"
WeakMap
dan
WeakSet
, yang penggunaannya meningkatkan kinerja "pengumpul sampah" - mekanisme yang bertanggung jawab untuk mengelola memori di mesin JS). Ini adalah struktur data yang sangat populer, yang, sebelum tampilan implementasi resmi mereka, harus ditiru menggunakan alat bahasa yang tersedia.
Ringkasan
Hari ini kami meninjau fitur dari standar ES2015, yang telah sangat memengaruhi kondisi bahasa saat ini. Topik kita berikutnya adalah fitur standar ES2016, ES2017 dan ES2018.
Pembaca yang budiman! Inovasi apa dari standar ES6 yang menurut Anda paling berguna?
