Pengantar ECMAScript 6 (ES-2015)

Pengantar ES6



Daftar isi
1. Templat literal
2. biarkan dan const
3. Ekspresi fungsi panah
4. Untuk ... dari
5. Nama properti yang dihitung
6. Object.assign ()
7. Parameter istirahat
8. Parameter default
9. Penugasan yang merusak
10. Peta
11. Atur
12. Kelas
13. Janji
14. Iterator
15. Generator
16. Sumbol

Templat literal (Templat string)


Templat literal adalah string literal yang memungkinkan penggunaan ekspresi di dalam. Dengan mereka Anda dapat menggunakan multiline literal dan interpolasi string.

Literal template dilampirkan dalam backticks (``) bukan double atau single. Mereka dapat berisi wildcard yang ditandai dengan tanda dolar dan kurung kurawal ($ {ekspresi}). Ekspresi subtitusi dan teks di antara keduanya diteruskan ke fungsi. Secara default, fungsi hanya menggabungkan semua bagian menjadi string. Jika ada ekspresi sebelum baris (ini tag), maka baris templat disebut "templat tag". Dalam kasus ini, ekspresi tag (biasanya fungsi) disebut dengan literal templat yang diproses, yang dapat Anda modifikasi sebelum hasilnya. Untuk menghindari backquote dalam literal templat, tentukan backslash \.

Literal multiline
Karakter baris baru adalah bagian dari wildcard literals. Menggunakan string biasa, penyisipan pembungkus akan membutuhkan sintaks berikut:
console.log('string text line 1\n' + 'string text line 2'); // "string text line 1 // string text line 2" 

Sama dengan menggunakan literal templat:
 console.log(`string text line 1 string text line 2`); // "string text line 1 // string text line 2" 


Interpolasi Ekspresi
Untuk menyisipkan ekspresi ke string reguler, Anda harus menggunakan sintaks berikut:
 var a = 5; var b = 10; console.log('Fifteen is ' + (a + b) + ' and not ' + (2 * a + b) + '.'); // "Fifteen is 15 and not 20." 


Sekarang, dengan bantuan literal templat, Anda dapat menggunakan `sintaksis gula`, yang membuat pergantian seperti itu lebih mudah dibaca:
 var a = 5; var b = 10; console.log(`Fifteen is ${a + b} and not ${2 * a + b}.`); // "Fifteen is 15 and not 20." 


Templat Bersarang
Terkadang, membuat pola adalah cara terpendek dan mungkin lebih mudah dibaca untuk membuat string. Cukup masukkan satu lagi di dalam template backquoted, bungkus mereka di substitusi $ {}. Misalnya, jika ekspresi itu benar, Anda bisa mengembalikan templat literal.
Dalam ES5:
 var classes = 'header' classes += (isLargeScreen() ? '' : item.isCollapsed ? ' icon-expander' : ' icon-collapser'); 

Di ES2015 dengan templat literal tanpa bersarang:
 const classes = `header ${ isLargeScreen() ? '' : (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`; 

Dalam ES2015 dengan literal templat bersarang:
 const classes = `header ${ isLargeScreen() ? '' : `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`; 


Templat tag
Bentuk literal templat yang diperluas adalah templat yang ditandai. Mereka memungkinkan Anda untuk mem-parsing templat literal menggunakan fungsi. Argumen pertama dari fungsi tersebut berisi array nilai string, dan sisanya berisi ekspresi dari pergantian. Akibatnya, fungsi tersebut harus mengembalikan string yang dirakit (atau sesuatu yang sama sekali berbeda, seperti yang akan ditampilkan nanti). Nama fungsinya bisa apa saja.
 var person = 'Mike'; var age = 28; function myTag(strings, personExp, ageExp) { var str0 = strings[0]; // "That " var str1 = strings[1]; // " is a " // ,     // (  )    , //    (""),    . // var str2 = strings[2]; var ageStr; if (ageExp > 99){ ageStr = 'centenarian'; } else { ageStr = 'youngster'; } //     ,     return `${str0}${personExp}${str1}${ageStr}`; } var output = myTag`That ${ person } is a ${ age }`; console.log(output);// That Mike is a youngster 

Fungsi tag tidak diperlukan untuk mengembalikan string.

Garis mentah
Properti mentah khusus, tersedia untuk argumen pertama dari template tag, memungkinkan Anda untuk mendapatkan string dalam bentuk yang dimasukkan, tanpa interpretasi.
 function tag(strings) { return strings.raw[0]; } tag`string text line 1 \\n string text line 2`; //  "string text line 1 \\n string text line 2", //  'n'    '\' 

Selain itu, ada metode String.raw () yang mengembalikan string sumber yang sama persis dengan fungsi templat default dan penggabungan string akan kembali bersamaan.

Di ECMAScript 2016, templat yang diberi tag ikuti aturan untuk keluar dari karakter berikut:
  • Karakter Unicode dimulai dengan "\ u", misalnya, \ u00A9
  • Poin kode Unicode dimulai dengan "\ u {}", misalnya, \ u {2F804}
  • Representasi karakter heksadesimal dimulai dengan "\ x", misalnya, \ xA9
  • representasi oktal karakter yang dimulai dengan "\", misalnya, \ 251


biarkan dan const


Cakupan variabel yang dideklarasikan oleh kata kunci let dan const adalah blok di mana mereka dideklarasikan, dan semuanya berada di bawah blok. Dalam hal ini, operasi direktif let mirip dengan direktif var. Perbedaan utama adalah bahwa ruang lingkup variabel yang dideklarasikan oleh direktif var adalah seluruh fungsi yang dideklarasikan. Selain variabel, nilai konstanta tidak dapat diubah oleh tugas baru, juga tidak dapat didefinisikan ulang. Saat mendeklarasikan variabel dengan kata kunci const, Anda harus menggunakan operator penugasan untuk menetapkan nilai konstanta.

Konstanta global tidak menjadi properti objek jendela, tidak seperti variabel var.
Diperlukan inisialisasi konstanta.
Anda harus menentukan nilai pada saat yang sama dengan deklarasi (intinya adalah bahwa nilai ini tidak lagi dapat diubah).
Mendeklarasikan variabel dengan kata kunci const menciptakan konstanta (referensi bernama baru ke wilayah memori) yang hanya baca.
Ini tidak berarti bahwa nilai yang ditunjukkan tidak berubah, tetapi itu berarti bahwa pengidentifikasi tidak dapat dipindahkan. Misalnya, jika sebuah titik konstan ke suatu objek, maka objek itu sendiri dapat dimodifikasi.
Nama konstanta tidak bisa bersamaan dengan nama fungsi atau variabel dengan cakupan yang sama.

Contoh perbedaan antara ruang lingkup global dan blok:
 function myFunction() { if (true) let a = 5; console.log(a); //SyntaxError   a     if if (true) var b = 5; console.log(b); //5   b     } 


Ekspresi fungsi panah


Ekspresi fungsi panah memiliki sintaks yang lebih pendek daripada ekspresi fungsional dan secara leksikal terikat dengan nilai ini (tetapi tidak terikat dengan ini sendiri, argumen, super, atau new.target). Ekspresi fungsi panah tidak memungkinkan Anda untuk menentukan nama, oleh karena itu fungsi panah bersifat anonim kecuali ditugaskan untuk apa pun.

Sintaks dasar
 (param1, param2, โ€ฆ, paramN) => { statements } (param1, param2, โ€ฆ, paramN) => expression // : (param1, param2, โ€ฆ, paramN) => { return expression; } //       : (singleParam) => { statements } singleParam => { statements } //       : () => { statements } () => expression // : () => { return expression; } 


Sintaks yang diperluas
 //     ,     params => ({foo: bar}) // Rest       (param1, param2, ...rest) => { statements } (param1 = defaultValue1, param2, โ€ฆ, paramN = defaultValueN) => { statements } //    var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6 

Informasi lebih lanjut tentang fungsi panah, dapat Anda temukan di sini .

Untuk ... dari


Untuk ... pernyataan mengeksekusi loop melalui objek iterable (termasuk Array, Map, Set, objek argumen dan sejenisnya), meminta setiap langkah iterasi operator untuk setiap nilai dari berbagai properti objek.

Mengapa TIDAK HARUS menggunakan for ... in loop untuk beralih? Karena tergantung pada mesinnya, JavaScript dapat beralih secara acak, yang dapat menyebabkan hasil yang tidak dapat diprediksi. Jika properti berubah dalam satu iterasi dan kemudian berubah lagi, nilainya dalam loop adalah nilai terakhirnya. Properti yang dihapus sebelum siklus mencapai itu tidak akan berpartisipasi di dalamnya. Properti yang ditambahkan ke objek dalam loop dapat dilewati. Secara umum, yang terbaik adalah tidak menambahkan, memodifikasi, atau menghapus properti dari objek selama iterasi jika Anda belum melewatinya. Tidak ada jaminan bahwa properti yang ditambahkan akan dikunjungi oleh siklus, diubah setelah perubahan dilakukan, dan dihapus setelah penghapusan. Selain itu, variabel iteratif adalah string, bukan angka, yang berarti bahwa jika Anda akan membuat perhitungan dengan variabel, Anda harus menggabungkan string daripada menambahkannya. Jadi untuk menghindari kesalahan logis, Anda sebaiknya tidak menggunakannya!

Tidak seperti for ... dari loop, for ... in loop mengembalikan semua properti yang disebutkan, termasuk yang dengan nama non-integer dan yang diwarisi.

Untuk ... dari sintaks loop
 for (var i of arr) //for ( of ) arr[i] = "something value" 

Contoh:
 Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {}; let iterable = [3, 5, 7]; iterable.foo = 'hello'; for (let i in iterable) console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom" for (let i in iterable) { if (iterable.hasOwnProperty(i)) console.log(i); //  0, 1, 2, "foo" } for (let i of iterable) console.log(i); // 3, 5, 7 

Setiap objek akan mewarisi metode objCustom dan setiap Array akan mewarisi metode arrCustom dengan membuat mereka di Object.prototype dan Array.prototype. Objek iterable akan mewarisi metode objCustom dan arrCustom karena pewarisan prototipe.

Loop hanya menampilkan properti enumerasi objek iterable, sesuai urutannya dibuat. Itu tidak mencetak nilai 3, 5, 7 dan halo karena mereka tidak dapat dihitung. Nama-nama properti dan metode ditampilkan, misalnya, arrCustom dan objCustom.

Loop mirip dengan yang sebelumnya, tetapi menggunakan hasOwnProperty () untuk memeriksa apakah properti objek ini adalah miliknya sendiri atau diwarisi. Hanya properti sendiri yang ditampilkan. Nama 0, 1, 2 dan foo hanya milik turunan dari objek (tidak diwarisi). Metode arrCustom dan objCustom bukan output karena mereka diwarisi.

Loop ini mem-bypass iterable dan menampilkan nilai-nilai dari objek iterable yang didefinisikan dalam metode iterating over, mis. bukan properti objek, tetapi nilai-nilai array 3, 5, 7.

Nama properti yang dihitung


Sintaks untuk mendeklarasikan objek dan elemennya mendukung nama properti yang dihitung. Ini memungkinkan Anda untuk menambahkan ekspresi ke tanda kurung [] yang akan dievaluasi sebagai nama properti. Itu menyerupai templat literal.

Contoh nama yang dihitung:
 var a = () => "world"; var a = { ["a" + (10 - 6)]: { ["some" + "string"]: true, [10 + 20]: 10, [`hello ${a()}`]: a() } } 



Object.assign ()


Metode Object.assign () digunakan untuk menyalin nilai dari semua properti enumerasinya sendiri dari satu atau lebih objek sumber ke objek target. Setelah menyalin, ia mengembalikan objek target.

Metode Object.assign () hanya menyalin properti enumerasi dan asli dari objek sumber ke objek target. Ia menggunakan metode [[Get]] internal pada objek sumber dan metode [[Set]] internal pada objek target, sehingga ia juga memanggil getter dan setter. Itulah sebabnya ia memberikan properti alih-alih hanya menyalin atau mendefinisikan properti baru. Perilaku ini dapat membuat metode tidak cocok untuk menyuntikkan properti baru ke dalam prototipe jika objek sumber yang disuntikkan berisi getter. Sebagai gantinya, untuk menyalin prototipe definisi properti, termasuk tanda enumerasi mereka, metode Object.getOwnPropertyDescriptor () dan Object.defineProperty () harus digunakan.

Properti tipe String dan Simbol disalin.

Dalam hal terjadi kesalahan, misalnya, ketika properti tidak dapat ditulisi, pengecualian TypeError dilemparkan, dan objek target tetap tidak berubah.

Perhatikan bahwa metode Object.assign () tidak melempar pengecualian jika nilai awal adalah nol atau tidak terdefinisi.

Contoh: Mengkloning Objek
 var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 } 

Contoh: Menggabungkan Objek
 var o1 = { a: 1 }; var o2 = { b: 2 }; var o3 = { c: 3 }; var obj = Object.assign(o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 },     . 


Parameter istirahat


Sintaks dari parameter fungsi yang tersisa memungkinkan Anda untuk mewakili sekumpulan argumen tak terbatas dalam bentuk array.

Jika argumen fungsi yang disebutkan terakhir memiliki awalan ..., maka secara otomatis menjadi array dengan elemen dari 0 hingga theArgs.length sesuai dengan jumlah argumen aktual yang diteruskan ke fungsi.

Sintaks
 function(a, b, ...theArgs) { // ... } 


Contoh menggunakan sintaks dari parameter yang tersisa:
 function name (a, b, ...c) {} name (0, 1, 2, 3,) 

Dalam contoh ini, a = 0 b = 1 c [0] = 2 c [1] = 3
Jika parameter yang tersisa tidak lulus, maka itu akan menjadi array kosong (tidak seperti parameter biasa, itu tidak akan pernah terdefinisi).

Sintaks ini dapat digunakan tidak hanya dalam argumen fungsi, tetapi juga di tempat lain, misalnya, untuk menyalin dan menggabungkan array:

 var a = [ 0, 1, 2 ]; var b = [ 3, 4, 5 ]; var c = [ ...a, ...b ]; // [ 0, 1, 2, 3, 4, 5 ] 


Parameter default


Parameter default memungkinkan Anda untuk mengatur parameter fungsi formal ke nilai default jika fungsi dipanggil tanpa argumen, atau jika parameter secara eksplisit diteruskan tidak terdefinisi.

Dalam JavaScript, parameter fungsi yang tidak lulus nilai saat dipanggil mengambil nilai default yang tidak ditentukan. Namun, dalam beberapa kasus mungkin berguna untuk menetapkan nilai default yang berbeda. Untuk kasus seperti itu pengaturan default dimaksudkan.

Nilai default ditetapkan untuk parameter formal hanya jika, selama panggilan fungsi, nilai untuk parameter ini tidak lulus atau tidak ditentukan secara eksplisit diteruskan.

Contoh menggunakan parameter default:
 function myFun(a=5) { return a*a; } console.log(myFun()); // 25 


Penugasan restrukturisasi


Sintaks penugasan merusak dalam ekspresi JavaScript memungkinkan Anda untuk mengambil data dari array atau objek menggunakan sintaksis yang mirip dengan mendeklarasikan array atau literal dalam suatu objek.

Pernyataan deklarasi objek atau array menyediakan cara mudah untuk membuat paket data yang homogen. Saat membuat paket seperti itu, Anda mendapat kesempatan untuk menggunakannya dengan cara apa pun yang memungkinkan. Anda juga dapat mengembalikannya dalam fungsi.

Salah satu cara utama untuk menggunakan penetapan destruktif adalah membaca struktur data dengan satu operator, meskipun Anda dapat menemukan banyak kegunaan lain selain ini.

Contoh penugasan destruktif:
 var a, b, rest; [a, b] = [1, 2]; console.log(a); // 1 console.log(b); // 2 [a, b, ...rest] = [1, 2, 3, 4, 5]; console.log(a); // 1 console.log(b); // 2 console.log(rest); // [3, 4, 5] ({a, b} = {a:1, b:2}); console.log(a); // 1 console.log(b); // 2 

Anda dapat melihat lebih banyak contoh di sini .

Peta


Peta - Objek yang berisi pasangan nilai kunci dan mempertahankan urutan penyisipan. Nilai apa pun (baik objek maupun primitif) dapat digunakan sebagai kunci.

Contoh:
 var myMap = new Map(); var keyObj = {}, keyFunc = function () {}, keyString = "a string"; //   myMap.set(keyString, "value associated with 'a string'"); myMap.set(keyObj, "value associated with keyObj"); myMap.set(keyFunc, "value associated with keyFunc"); myMap.size; // 3 //   myMap.get(keyString); // "value associated with 'a string'" myMap.get(keyObj); // "value associated with keyObj" myMap.get(keyFunc); // "value associated with keyFunc" myMap.get("a string"); // "value associated with 'a string'" //   keyString === 'a string' myMap.get({}); // undefined,   keyObj !== {} myMap.get(function() {}) // undefined,   keyFunc !== function () {} 

Perbedaan Peta dari Objek:

  • Kunci objek adalah Garis dan Simbol, sedangkan nilai apa pun bisa menjadi kunci Peta, termasuk fungsi, objek, dan primitif.
  • Tidak seperti Objek, tombol di Peta diurutkan. Jadi, selama iterasi Peta, kunci dikembalikan dalam urutan penyisipan.
  • Anda dapat dengan mudah mendapatkan jumlah elemen dalam Peta menggunakan properti ukuran, sedangkan jumlah elemen dalam Objek hanya dapat ditentukan secara manual.
  • Peta adalah objek yang dapat diulang dan dapat diulangi secara langsung, sedangkan Objek membutuhkan penerimaan manual dari daftar kunci dan iterasi mereka.
  • Objek memiliki prototipe dan karenanya memiliki seperangkat kunci standar, yang, jika ceroboh, dapat bersinggungan dengan kunci Anda. Sejak rilis ES5, ini dapat diubah menggunakan map = Object.create (null).
  • Peta dapat memiliki kinerja yang lebih baik jika sering menambah atau menghapus kunci.

Properti dan metode:

  • Map.prototype.size - Mengembalikan jumlah pasangan kunci \ nilai pada Peta
  • Map.prototype.set (kunci, nilai) - Menambahkan pasangan kunci lulus \ nilai ke Peta. Jika kunci yang ditentukan sudah ada, maka akan ditimpa dengan nilai baru.
  • Map.prototype.get (key) - Mengembalikan nilai dari kunci yang dikirimkan. Jika tidak ada kunci, maka undefined akan kembali
  • Map.prototype.has (kunci) - Mengembalikan nilai true jika kunci yang disahkan ada dan salah jika tidak
  • Map.prototype.delete (key) - Menghapus pasangan kunci \ nilai yang ditentukan dan mengembalikan true. Mengembalikan nilai false jika kunci tidak ada.
  • Map.prototype.clear () - Menghapus semua pasangan kunci \ nilai dari Peta
  • Map.prototype.keys () - Mengembalikan iterator kunci pada Peta untuk setiap elemen
  • Map.prototype.values โ€‹โ€‹() - Mengembalikan iterator nilai pada Peta untuk setiap elemen
  • Map.prototype.entries () - Mengembalikan iterator array [kunci, nilai] pada Peta untuk setiap elemen


Setel


Memungkinkan Anda menyimpan nilai unik dari jenis apa pun, baik primitif maupun jenis objek lainnya.

Tetapkan objek mewakili koleksi nilai yang bisa Anda lintasi dalam urutan elemen yang dimasukkan. Nilai elemen dalam Set dapat hadir hanya dalam satu contoh, yang memastikan keunikannya dalam koleksi Set.

Properti dan Metode Instance Set
  • size - Mengembalikan jumlah elemen dalam objek Set.
  • add (value) - Menambahkan elemen baru dengan nilai yang diberikan ke objek Set. Mengembalikan objek Set.
  • clear () - Menghapus semua elemen dari objek Set.
  • delete (value) - Menghapus elemen yang terkait dengan nilai dan mengembalikan nilai yang memiliki (nilai) sebelumnya akan kembali. memiliki (nilai) akan mengembalikan false nanti.
  • entri () - Mengembalikan objek Iterator baru yang berisi larik [nilai, nilai] untuk setiap elemen di objek Tetapkan dalam urutan penyisipan. Ini disimpan mirip dengan objek Peta, sehingga setiap entri memiliki nilai yang sama untuk kunci dan nilainya di sini.
  • forEach (callbackFn [, thisArg]) - Memanggil callbackFn satu kali untuk setiap nilai yang ada di objek Set, dalam urutan penyisipan. Jika thisArg ditentukan untuk masing-masing, ini akan digunakan sebagai nilai ini untuk setiap panggilan balik.
  • has (value) - Mengembalikan nilai boolean yang mengonfirmasi apakah elemen dengan nilai yang diberikan ada di objek Set atau tidak.
  • values โ€‹โ€‹() - Mengembalikan objek Iterator baru yang berisi nilai untuk setiap elemen di objek Set dalam urutan penyisipan.

Menggunakan Set Object
 var mySet = new Set(); mySet.add(1); // Set { 1 } mySet.add(5); // Set { 1, 5 } mySet.add(5); // Set { 1, 5 } mySet.add("some text"); // Set { 1, 5, 'some text' } var o = {a: 1, b: 2}; mySet.add(o); mySet.add({a: 1, b: 2}); //  o    ,      mySet.has(1); // true mySet.has(3); // false, 3     set mySet.has(5); // true mySet.has(Math.sqrt(25)); // true mySet.has("Some Text".toLowerCase()); // true mySet.has(o); // true mySet.size; // 5 mySet.delete(5); //  5  set mySet.has(5); // false, 5   mySet.size; // 4,     console.log(mySet); // Set {1, 'some text', Object {a: 1, b: 2}, Object {a: 1, b: 2}} 

Set Bypass
 //    : 1, "some text", {"a": 1, "b": 2} for (let item of mySet) console.log(item); //    : 1, "some text", {"a": 1, "b": 2} for (let item of mySet.keys()) console.log(item); //    : 1, "some text", {"a": 1, "b": 2} for (let item of mySet.values()) console.log(item); //    : 1, "some text", {"a": 1, "b": 2} //(key  value    ) for (let [key, value] of mySet.entries()) console.log(key); //  Set  Array var myArr = Array.from(mySet); // [1, "some text", {"a": 1, "b": 2}] //       HTML  mySet.add(document.body); mySet.has(document.querySelector("body")); // true //   Array  Set   mySet2 = new Set([1,2,3,4]); mySet2.size; // 4 [...mySet2]; // [1,2,3,4] //      var intersection = new Set([...set1].filter(x => set2.has(x))); //      var difference = new Set([...set1].filter(x => !set2.has(x))); //   set   forEach mySet.forEach(function(value) { console.log(value); }); // 1 // 2 // 3 // 4 



Kelas


Kelas-kelas dalam JavaScript diperkenalkan dalam ECMAScript 2015 dan merupakan sintaksis gula atas pewarisan prototipe dalam JavaScript. Sintaks kelas tidak memperkenalkan model berorientasi objek baru, tetapi menyediakan cara yang lebih sederhana dan lebih intuitif untuk membuat objek dan mengatur warisan.

Kelas sebenarnya "fungsi khusus", jadi sama seperti Anda mendefinisikan fungsi (ekspresi fungsi dan deklarasi fungsi), Anda dapat mendefinisikan kelas dengan: deklarasi kelas dan ekspresi kelas.

Perbedaan antara deklarasi fungsi dan deklarasi kelas adalah bahwa deklarasi fungsi diangkat, sedangkan deklarasi kelas tidak. Oleh karena itu, Anda harus mendeklarasikan kelas Anda dan baru kemudian bekerja dengannya, jika tidak pengecualian dari ReferenceError akan dibuang.

Deklarasi kelas


Cara pertama untuk mendefinisikan kelas adalah dengan deklarasi kelas. Untuk melakukan ini, gunakan kata kunci kelas dan tentukan nama kelas (dalam contoh, "myClass").
 class myClass{ constructor(height, width) { this.height = height; this.width = width; } } 

Cara kedua untuk mendefinisikan kelas adalah ekspresi kelas. Anda dapat membuat ekspresi bernama dan tanpa nama. Dalam kasus pertama, nama ekspresi kelas berada dalam cakupan lokal kelas dan dapat diperoleh melalui properti kelas itu sendiri, dan bukan turunannya.
 //  var myClass = class { constructor(height, width) { this.height = height; this.width = width; } }; //  var myClass = class myClass { constructor(height, width) { this.height = height; this.width = width; } }; 

Ekspresi kelas tunduk pada masalah mengangkat yang sama dengan deklarasi kelas!

Badan deklarasi kelas dan ekspresi kelas dieksekusi dalam mode ketat.
Mode ketat mengubah sintaks dan perilaku runtime.
Agar lebih tepat, mode ketat ditandai dengan yang berikut:
  • Konversi kesalahan menjadi pengecualian
  • perubahan yang menyederhanakan perhitungan variabel dalam kasus tertentu menggunakan namanya;
  • , eval arguments;
  • , ยซยป JavaScript;


  1. .
  2. .
  3. , , .
  4. ( ).
  5. , , . , .
  6. . .
  7. Sintaksis sistem angka oktal dilarang.
  8. Menyetel properti dengan nilai primitif dilarang.

Penyederhanaan pekerjaan dengan variabel
Mode ketat menyederhanakan perbandingan nama variabel dengan tempat definisi dalam kode.
  1. Dilarang menggunakan dengan. Masalahnya dengan saat runtime, nama apa pun di dalam blok dapat merujuk ke properti objek yang sedang diproses atau variabel dalam konteks sekitarnya (atau bahkan global) - tidak mungkin untuk mengetahui hal ini sebelumnya. Alternatif sederhana dengan yang sudah ada - menugaskan objek ke variabel dengan nama pendek dan kemudian mengakses properti yang diinginkan sebagai properti dari variabel ini.
  2. eval () dalam mode ketat tidak menambahkan variabel baru ke konteks sekitarnya.
  3. Dilarang menghapus nama-nama sederhana.

Penyederhanaan eval dan argumen
Mode ketat mengurangi jumlah keanehan dalam perilaku argumen dan eval, yang keduanya mencampur sejumlah sihir ke dalam kode reguler. Jadi eval menambah atau menghapus variabel dan mengubah nilainya, dan variabel argumen dapat mengejutkan Anda dengan properti yang diindeks, yang merupakan referensi (sinonim) untuk argumen fungsi bernama.
  1. Argumen dan argumen kata kunci tidak dapat diganti atau dimodifikasi.
  2. Bidang objek argumen tidak terkait dengan argumen fungsi yang disebutkan, tetapi merupakan duplikat nilai mereka.
  3. Properti arguments.callee tidak didukung. Dalam kode reguler, properti arguments.callee merujuk ke fungsi itu sendiri, untuk permohonan objek argumen yang dibuat.

JavaScript "Aman"
Beberapa situs web memberi pengguna kemampuan untuk menulis JavaScript yang akan dieksekusi di situs atas nama pengguna lain. Di browser, JavaScript mungkin memiliki akses ke informasi pribadi, yang merupakan lubang keamanan dalam JavaScript.
  1. Nilai diteruskan ke fungsi karena ini tidak dilemparkan ke objek dalam mode ketat.
  2. Tidak mungkin untuk "menjalankan" tumpukan JavaScript melalui ekstensi ECMAScript dasar.
  3. Dalam fungsi, properti argumen tidak lagi menyediakan akses ke variabel yang dibuat di dalam fungsi.

Anda dapat melihat spesifikasi ECMAScript 5.1 untuk mempelajari lebih lanjut tentang mode Ketat.
Dan juga dokumentasi dari Mozilla.

Konstruktor


konstruktor adalah metode khusus yang digunakan untuk membuat dan menginisialisasi objek yang dibuat menggunakan kelas.
 class Student { constructor(name) { this.name = name; } } var robert = new Student('Robert'); console.log(robert.name); // Outputs 'Robert' 

Saat membuat objek baru dari kelas, konstruktor () akan diluncurkan, yang diperlukan untuk menginisialisasi objek.

Hanya ada satu metode dalam kelas yang disebut konstruktor. Jika kelas berisi lebih dari satu konstruktor, pengecualian SyntaxError akan dibuang.

Kata kunci super dapat digunakan dalam konstruktor untuk memanggil konstruktor dari kelas induk.

Jika Anda tidak mendefinisikan metode konstruktor, maka konstruktor default akan digunakan.
Untuk kelas dasar, konstruktor default adalah:
 constructor() {} 

Untuk kelas turunan, konstruktor default adalah:
 constructor(...args) { super(...args); } 


Metode


Sintaks deklarasi metode:
 var obj = { property([parameters]) {}, get property() {}, set property(value) {}, * generator() {} }; 

Singkatan dari Metode Generator
 var obj = { * g() { var index = 0; while(true) yield index++; } }; var it = obj.g(); console.log(it.next().value); // 0 console.log(it.next().value); // 1 


Semua definisi metode kecuali metode generator tidak dapat menjadi konstruktor dan akan menghasilkan TypeError jika Anda mencoba untuk instantiate.

Nama Properti yang Dihitung
 var obj = { ["foo" + 2](){ return 2; } console.log(obj.foo2()); // 2 }; 


Kata kunci statis mendefinisikan metode statis untuk suatu kelas. Metode statis dipanggil tanpa membuat instance kelas mereka, dan tidak dapat dipanggil pada instance kelas.

Sintaks getter dan setter
 class Student { constructor(name) { this.name = name; } get Name() { return this.name; } set Name(newName) { if(typeof(newName) != "string") throw new Error("Name is not a string!"); else this.name = newName; // Robert } } var robert = new Student('robert'); robert.Name = "Robert"; console.log(robert.Name); 

  • setter - Diperlukan untuk validasi parameter tertulis (seperti pada contoh di atas)
  • getter - Diperlukan untuk mendapatkan properti (meskipun mereka dapat diperoleh secara langsung). Tidak dapat memiliki argumen

Tidak ada enkapsulasi bawaan di ES6, tetapi Anda dapat mengaturnya sendiri. Misalnya, seperti ini:

 var Student = (function () { let privateProps = new WeakMap(); class Person { constructor(name, Age) { this.name = name; // public privateProps.set(this, {age: Age}); // private } get Age() { return privateProps.get(this).age; } set Age (newAge) { privateProps.set(this, {age: newAge}); } } return Person; })(); var robert = new Student('Robert', 19); robert.Age = 20; console.log(robert.Age); // 20 


Warisan


Kata kunci extends digunakan dalam deklarasi kelas dan ekspresi kelas untuk membuat kelas yang merupakan anak dari kelas lain.

 class Person { constructor (age) { this.age = age; } sayAge () { return this.age; } } class Student extends Person { constructor (name, age) { super(age); this.name = name; } sayFull () { return `Hello my name is ${this.name} and I'm ${super.sayAge()} years old`; } } var robert = new Student("Robert", 19); console.log(robert.sayFull()); // Hello my name is Robert and I'm 19 years old 


Di konstruktor, kata kunci super () digunakan sebagai fungsi yang memanggil konstruktor induk. Itu harus dipanggil sebelum panggilan pertama ke kata kunci ini di badan konstruktor. Kata kunci super juga dapat digunakan untuk memanggil fungsi objek induk.

Ketika Anda mengganti metode kelas induk di kelas anak, metode kelas anak akan dipanggil secara default, tetapi Anda dapat secara eksplisit memanggil metode kelas induk menggunakan fungsi super ().
 class obj { constructor(name){ this.name = name; } displayName(){ return this.name.length; } } undefined class obj_2 extends obj { constructor(name) { super(name); } displayName() { //     return [this.name, super.displayName()]; } } var Obj = new obj_2("obj_2"); console.log(Obj.displayName()); // Array [ "obj_2", 5 ] 


Memperluas objek inline dengan extends
Contoh ini memperluas objek Date inline.
 class myDate extends Date { constructor() { super(); } getFormattedDate() { var months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; return this.getDate() + '-' + months[this.getMonth()] + '-' + this.getFullYear(); } } 


Janji


Objek Janji digunakan untuk perhitungan yang ditangguhkan dan tidak sinkron.

Janji bisa di tiga negara:
  • tertunda: keadaan awal, tidak selesai dan tidak ditolak.
  • (fulfilled): .
  • (rejected): .

(pending), (fulfilled), (), (rejected), . , then. ( , , .. ยซ ยป, , , DOM.)

Promise.prototype.then() Promise.prototype.catch() , , .
gambar

(promise)
Objek Janji dibuat menggunakan kata kunci baru dan konstruktornya. Konstruktor Janji mengambil argumen yang disebut fungsi pelaksana sebagai argumen. Fungsi ini harus menerima dua fungsi panggilan balik sebagai parameter. Yang pertama (tekad) dipanggil ketika operasi asinkron selesai dengan sukses dan mengembalikan hasil eksekusi sebagai nilai. Callback kedua (tolak) dipanggil ketika operasi gagal, dan mengembalikan nilai yang menunjukkan alasan kegagalan, paling sering objek kesalahan.
 const myPromise = new Promise((resolve, reject) => { //   ,    : resolve(someValue); //   //  reject("failure reason"); //  }); 

Objek fungsi dengan dua argumen, menyelesaikan dan menolak, menyebabkan janji untuk berhasil, yang kedua menolaknya.

Untuk menyediakan fungsi dengan fungsionalitas janji, Anda hanya perlu mengembalikan objek Janji di dalamnya.
 function myAsyncFunction(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = () => resolve(xhr.responseText); xhr.onerror = () => reject(xhr.statusText); xhr.send(); }); } 

Menggunakan. kemudian penangan eksekusi dan penolakan dilampirkan.

Metode
  • Promise.all (iterable) - Menunggu semua janji untuk dieksekusi atau ditolak untuk salah satu dari mereka. Mengembalikan janji yang akan dieksekusi setelah semua janji dieksekusi di iterable. Jika ada janji yang ditolak, Janji. Semua juga akan ditolak.
  • Promise.allSettled (iterable) - Menunggu untuk menyelesaikan semua janji yang diterima (baik eksekusi dan penolakan). Mengembalikan janji yang dieksekusi ketika semua janji yang diterima selesai (dieksekusi atau ditolak), yang berisi berbagai hasil eksekusi dari janji yang diterima.
  • Promise.race (iterable) - Menunggu eksekusi atau penolakan terhadap janji yang diterima. Mengembalikan janji yang akan dieksekusi atau ditolak dengan hasil pelaksanaan janji yang dieksekusi atau ditolak pertama dari .iterable.
  • Promise.reject (reason) - Mengembalikan janji yang ditolak karena alasan.
  • Promise.resolve (value) - Mengembalikan janji yang dieksekusi dengan nilai hasil.

Prototipe janji
  • catch (onRejected) - Menambahkan fungsi callback untuk menangani penolakan janji, yang mengembalikan janji baru yang dibuat dengan nilai yang diteruskan jika dipanggil, atau nilai penyelesaian asli jika janji itu dibuat.
  • then (onFulfilled, onRejected) - Menambahkan pemenuhan janji dan penangan penolakan, dan mengembalikan janji baru yang dieksekusi dengan nilai penangan yang disebut, atau nilai asli jika janji tidak diproses (mis. jika penangan onFulfilled atau onRejected yang bersangkutan bukan fungsi).


Membuat permintaan http asinkron:
 const URL = "https://getfestivo.com/v1/holidays?api_key=f8f42551-eb66-49d2-bcba-b8e42727ddfb&country=US&year=2019"; //  API      function asyncHttpRequest (url) { return new Promise((resolve, reject) => { //  promise if (url == undefined) //     url reject(new Error("Expected url and received nothing")); else { resolve(() => { fetch(url).then((response) => { //   return response.json(); //    JSON   }).then((myJson) => { return(console.log(myJson)); //      }); }); } } );} asyncHttpRequest(URL).then((result) => result(), (error) => console.log(error)); 



Anda bisa mendapatkan lebih banyak contoh dan informasi tentang janji di dokumentasi resmi , serta di dokumentasi Mozilla .

Iterator


Memproses setiap item dalam koleksi adalah operasi yang sangat umum. JavaScript menyediakan beberapa cara untuk beralih pada koleksi, dari yang sederhana untuk loop ke map (), filter (), dan pemahaman array. Iterator dan generator mengimplementasikan konsep enumerasi langsung ke inti bahasa dan menyediakan mekanisme untuk mengatur perilaku untuk ... loop.

Objek adalah iterator jika dapat mengakses elemen koleksi satu per satu, sambil melacak posisinya saat ini dalam urutan ini. Dalam JavaScript, iterator adalah objek yang menyediakan metode next () yang mengembalikan elemen berikutnya dari suatu urutan. Metode ini mengembalikan objek dengan dua properti: selesai dan nilai.

Setelah dibuat, objek iterator dapat digunakan secara eksplisit dengan memanggil metode next ().

Iterable - Ini adalah objek yang isinya dapat dilingkarkan.
Objek iterable berbeda dari yang tidak iterable karena memiliki metode khusus yang mengembalikan objek untuk akses ke mana simbol khusus digunakan: Symbol.iterator
 Iterable { [Symbol.iterator]() } 

Objek yang mengembalikan metode ini secara resmi disebut iterator.
Iterator hanya memiliki satu metode next ()
 Iterator { next(); } 

Yang mengembalikan objek (sebut saja itreratorResult) dengan dua properti selesai dan nilai
 IteratorResult { done, value } 

selesai menunjukkan apakah masih ada nilai dalam urutan yang dicari, dan nilai berisi elemen berikutnya dari urutan.


Setelah inisialisasi, metode next () dapat dipanggil untuk mengakses pasangan kunci-nilai pada objek satu per satu.

Objek iterable jika mendefinisikan metode untuk menghitung nilai, yaitu, misalnya, bagaimana nilai dihitung dalam for..of konstruksi. Beberapa tipe bawaan, seperti Array atau Map, dapat diubah secara default, sedangkan tipe lainnya, seperti Object, tidak.

Agar dapat diulang, suatu objek harus mengimplementasikan metode iterator, yang berarti bahwa itu (atau salah satu objek dalam rantai prototipe) harus memiliki properti yang disebut Symbol.iterator.

Seperti inilah tampilan iterator standar:
 function makeIterator(array){ var nextIndex = 0; return { next: function(){ return nextIndex < array.length ? { value: array[nextIndex++], done: false } : { done: true }; } } } 


Generator


Generator adalah jenis fungsi khusus yang berfungsi seperti pabrik iterator. Suatu fungsi menjadi generator jika mengandung satu atau lebih pernyataan hasil dan menggunakan sintaks fungsi *.

Generator adalah jenis fungsi baru yang dapat menjeda eksekusi dan mengembalikan hasil antara dan melanjutkan eksekusi nanti.

Mari kita lihat fungsi reguler yang menghitung dan mengembalikan hasilnya:
 function myFunction (a) { a = a*2; a = a - 1; return a; } console.log(myFunction(5)); // 9 

Sekarang lihat fungsi generator yang serupa:
 function* generator(a) { a = a*2; yield a; a = a - 1; yield a; } var it = generator(5); console.log(it.next().value); // 10 console.log(it.next().value); // 9</i> 

Seperti yang dinyatakan sebelumnya, generator dapat menjeda eksekusi dan mengembalikan hasil antara. Contoh ini menunjukkan bahwa pada saat panggilan pertama, fungsinya seolah-olah menunda eksekusi pada breakpoint pertama dan mengembalikan hasil dari ekspresi pertama. Dalam panggilan kedua, fungsi berlanjut dari breakpoint sebelumnya dan bergerak ke yang berikutnya, mengembalikan hasil dari ekspresi berikutnya.

Function generator menyediakan alat yang ampuh untuk menulis fungsi berurutan yang kompleks.

Generator menghitung hasil dari ekspresi hasil sesuai permintaan, yang memungkinkan mereka untuk bekerja secara efisien dengan urutan dengan kompleksitas komputasi yang tinggi, atau bahkan urutan tanpa batas.

Metode () selanjutnya juga mengambil nilai yang dapat digunakan untuk mengubah keadaan internal generator. Nilai yang diteruskan ke next () akan dianggap sebagai hasil dari ekspresi hasil terakhir yang menjeda generator.

Anda bisa memaksa generator untuk melempar eksepsi dengan memanggil metode throw () dan meneruskan nilai eksepsi yang harus dilemparkan sebagai parameter. Pengecualian ini akan dilempar dari konteks jeda generator saat ini seolah-olah pernyataan hasil jeda saat ini adalah pernyataan melempar.

Jika pernyataan hasil tidak terjadi selama pemrosesan pengecualian yang dilemparkan, maka pengecualian dilewatkan di atas melalui panggilan throw (), dan hasil dari panggilan berikutnya ke next () akan dilakukan properti yang sama dengan true.

Generator memiliki metode pengembalian (nilai) yang mengembalikan nilai yang diberikan dan menghentikan generator.

Simbol


Simbol adalah tipe data primitif yang instansinya unik dan tidak dapat diubah.

Dalam runtime JavaScript, nilai "simbol" dibuat dengan memanggil fungsi Symbol (), yang secara dinamis menciptakan nilai anonim dan unik. Satu-satunya penggunaan yang masuk akal adalah untuk menyimpan karakter, dan kemudian menggunakan nilai yang disimpan untuk membuat properti objek.

Ketika karakter digunakan sebagai pengidentifikasi dalam tugas properti, properti (misalnya, karakter) adalah anonim; dan juga tidak terhitung. Karena properti tidak dapat dihitung, properti tidak akan ditampilkan dalam loop "for (... in ...)", dan karena properti tersebut anonim, properti tidak akan ditampilkan di larik hasil "Object.getOwnPropertyNames ()". Akses ke properti ini dapat diperoleh dengan menggunakan nilai awal dari simbol yang membuatnya, atau dengan mengulangi melalui larik hasil "Object.getOwnPropertySymbols ()".


Jadi, Anda dapat membuat properti karakter:
 var user = { name: "Alex", [Symbol("password")]: "12hsK3I" } 

Untuk mendapatkan larik objek karakter, gunakan properti Object.getOwnPropertySymbols (obj);
Untuk mengakses di mana saja dalam kode Anda, gunakan metode Symbol.for () dan Symbol.keyFor ().

Untuk informasi lebih lanjut tentang tipe data Sumbol, lihat di dokumentasi resmi , dan juga di dokumentasi Mozilla.

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


All Articles