ES6 - Iterator
Pengantar Iterator
Iterator adalah sebuah objek yang memungkinkan kita mengakses kumpulan objek satu per satu.
Jenis bawaan berikut secara default dapat diulang -
- String
- Array
- Map
- Set
Sebuah objek dipertimbangkan iterable, jika objek mengimplementasikan fungsi yang kuncinya adalah [Symbol.iterator]dan mengembalikan iterator. A for ... of loop dapat digunakan untuk mengulang koleksi.
Contoh
Contoh berikut mendeklarasikan sebuah array, menandai, dan mengulanginya dengan menggunakan file for..of loop.
<script>
let marks = [10,20,30]
//check iterable using for..of
for(let m of marks){
console.log(m);
}
</script>
Output dari kode di atas akan seperti yang diberikan di bawah ini -
10
20
30
Contoh
Contoh berikut mendeklarasikan sebuah array, menandai dan mengambil objek iterator. Itu[Symbol.iterator]()dapat digunakan untuk mengambil objek iterator. Metode next () dari iterator mengembalikan objek dengan'value' dan 'done'properti. 'selesai' adalah Boolean dan mengembalikan nilai true setelah membaca semua item dalam koleksi.
<script>
let marks = [10,20,30]
let iter = marks[Symbol.iterator]();
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
</script>
Output dari kode di atas akan seperti gambar di bawah ini -
{value: 10, done: false}
{value: 20, done: false}
{value: 30, done: false}
{value: undefined, done: true}
Iterable Kustom
Jenis tertentu dalam JavaScript dapat diulang (Misalnya Array, Peta, dll.) Sementara yang lain tidak (Misalnya Kelas). Jenis JavaScript yang tidak dapat diulang secara default dapat diulang dengan menggunakan protokol yang dapat diulang.
Contoh berikut mendefinisikan kelas bernama CustomerListyang menyimpan banyak objek pelanggan sebagai larik. Setiap objek pelanggan memiliki properti firstName dan lastName.
Untuk membuat kelas ini dapat diulang, kelas tersebut harus diimplementasikan [Symbol.iterator]()fungsi. Fungsi ini mengembalikan objek iterator. Objek iterator memiliki fungsinext yang mengembalikan sebuah objek {value:'customer',done:true/false}.
<script>
//user defined iterable
class CustomerList {
constructor(customers){
//adding customer objects to an array
this.customers = [].concat(customers)
}
//implement iterator function
[Symbol.iterator](){
let count=0;
let customers = this.customers
return {
next:function(){
//retrieving a customer object from the array
let customerVal = customers[count];
count+=1;
if(count<=customers.length){
return {
value:customerVal,
done:false
}
}
//return true if all customer objects are iterated
return {done:true}
}
}
}
}
//create customer objects
let c1={
firstName:'Sachin',
lastName:'Tendulkar'
}
let c2={
firstName:'Rahul',
lastName:'Dravid'
}
//define a customer array and initialize it let customers=[c1,c2]
//pass customers to the class' constructor
let customersObj = new CustomerList(customers);
//iterating using for..of
for(let c of customersObj){
console.log(c)
}
//iterating using the next() method
let iter = customersObj[Symbol.iterator]();
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
</script>
Output dari kode di atas adalah sebagai berikut -
{firstName: "Sachin", lastName: "Tendulkar"}
{firstName: "Rahul", lastName: "Dravid"}
{
done: false
value: {
firstName: "Sachin",
lastName: "Tendulkar"
}
}
{
done: false
value: {
firstName: "Rahul",
lastName: "Dravid"
}
}
{done: true}
Generator
Sebelum ES6, fungsi dalam JavaScript mengikuti model run-to finish. ES6 memperkenalkan fungsi yang dikenal sebagai Generator yang dapat berhenti di tengah jalan dan kemudian melanjutkan dari tempat berhenti.
Generator mengawali nama fungsi dengan karakter asterisk * dan berisi satu atau lebih yieldpernyataan. Ituyield kata kunci mengembalikan objek iterator.
Sintaksis
function * generator_name() {
yield value1
...
yield valueN
}
Contoh
Contoh tersebut mendefinisikan fungsi generator getMarksdengan tiga pernyataan hasil. Tidak seperti fungsi normal, filegenerator function getMarks(), saat dipanggil, tidak menjalankan fungsi tetapi mengembalikan objek iterator yang membantu Anda mengeksekusi kode di dalam fungsi generator.
Pada panggilan pertama ke markIter.next()operasi di awal akan berjalan dan pernyataan hasil menghentikan sementara eksekusi generator. Panggilan berikutnya kemarkIter.next() akan melanjutkan fungsi generator hingga berikutnya yield ekspresi.
<script>
//define generator function
function * getMarks(){
console.log("Step 1")
yield 10
console.log("Step 2")
yield 20
console.log("Step 3")
yield 30
console.log("End of function")
}
//return an iterator object
let markIter = getMarks()
//invoke statements until first yield
console.log(markIter.next())
//resume execution after the last yield until second yield expression
console.log(markIter.next())
//resume execution after last yield until third yield expression
console.log(markIter.next())
console.log(markIter.next()) // iteration is completed;no value is returned
</script>
Output dari kode di atas akan seperti yang disebutkan di bawah ini -
Step 1
{value: 10, done: false}
Step 2
{value: 20, done: false}
Step 3
{value: 30, done: false}
End of function
{value: undefined, done: true}
Contoh
Contoh berikut membuat urutan bilangan genap yang tak terbatas
* Fungsi generator evenNumberGenerator.
Kami dapat melakukan iterasi melalui semua bilangan genap dengan menggunakan next() atau menggunakan for of loop seperti yang ditunjukkan di bawah ini
<script>
function * evenNumberGenerator(){
let num = 0;
while(true){
num+=2
yield num
}
}
// display first two elements
let iter = evenNumberGenerator();
console.log(iter.next())
console.log(iter.next())
//using for of to iterate till 12
for(let n of evenNumberGenerator()){
if(n==12)break;
console.log(n);
}
</script>
Output dari kode di atas adalah sebagai berikut -
{value: 2, done: false}
{value: 4, done: false}
2
4
6
8
10