Сборка от 17 марта 2017 г



Download 9,9 Mb.
bet271/349
Sana26.04.2022
Hajmi9,9 Mb.
#582433
TuriУчебник
1   ...   267   268   269   270   271   272   273   274   ...   349
Bog'liq
ilja kantor sovremennyj uchebnik-1chast PdfToWord

Итераторы


В современный JavaScript добавлена новая концепция «итерируемых» (iterable) объектов.


Итерируемые или, иными словами, «перебираемые» объекты – это те, содержимое которых можно перебрать в цикле.


Например, перебираемым объектом является массив. Но не только он. В браузере существует множество объектов, которые не являются массивами, но содержимое которых можно перебрать (к примеру, список DOM‑узлов).


Для перебора таких объектов добавлен новый синтаксис цикла: for..of . Например:

'use strict';


let arr = [1, 2, 3]; // массив — пример итерируемого объекта for (let value of arr) {
alert(value); // 1, затем 2, затем 3
}

Также итерируемой является строка:


'use strict';


for (let char of "Привет") {


alert(char); // Выведет по одной букве: П, р, и, в, е, т
}

Итераторы – расширяющая понятие «массив» концепция, которая пронизывает современный стандарт JavaScript сверху донизу.


Практически везде, где нужен перебор, он осуществляется через итераторы. Это включает в себя не только строки, массивы, но и вызов функции с оператором spread f(...args) , и многое другое.


В отличие от массивов, «перебираемые» объекты могут не иметь «длины» length . Как мы увидим далее, итераторы дают возможность сделать
«перебираемыми» любые объекты.


Свой итератор


Допустим, у нас есть некий объект, который надо «умным способом» перебрать.


Например, range – диапазон чисел от from до to , и мы хотим, чтобы for (let num of range) «перебирал» этот объект. При этом под перебором мы подразумеваем перечисление чисел от from до to .


Объект range без итератора:

let range = { from: 1,


to: 5
};

// хотим сделать перебор


// for (let num of range) ...

Для возможности использовать объект в for..of нужно создать в нём свойство с названием Symbol.iterator (системный символ).


При вызове метода Symbol.iterator перебираемый объект должен возвращать другой объект («итератор»), который умеет осуществлять перебор. По стандарту у такого объекта должен быть метод next() , который при каждом вызове возвращает очередное значение и окончен ли перебор.


В коде это выглядит следующим образом:
'use strict';

let range = { from: 1,


to: 5
}

// сделаем объект range итерируемым range[Symbol.iterator] = function() {


let current = this.from; let last = this.to;


// метод должен вернуть объект с методом next() return {


next() {
if (current <= last) { return {
done: false, value: current++
};
} else { return {
done: true
};
}
}

}
};


for (let num of range) {


alert(num); // 1, затем 2, 3, 4, 5
}

Как видно из кода выше, здесь имеет место разделение сущностей:





  • Перебираемый объект range сам не реализует методы для своего перебора.

  • Для этого создаётся другой объект, который хранит текущее состояние перебора и возвращает значение. Этот объект называется итератором и возвращается при вызове метода range[Symbol.iterator] .

  • У итератора должен быть метод next() , который при каждом вызове возвращает объект со свойствами:

    • value – очередное значение,

    • done – равно false если есть ещё значения, и true – в конце.

Конструкция for..of в начале своего выполнения автоматически вызывает Symbol.iterator() , получает итератор и далее вызывает метод next() до получения done: true . Такова внутренняя механика. Внешний код при переборе через for..of видит только значения.


Такое отделение функционала перебора от самого объекта даёт дополнительную гибкость. Например, объект может возвращать разные итераторы в зависимости от своего настроения и времени суток. Однако, бывают ситуации когда оно не нужно.
Если функционал по перебору (метод next ) предоставляется самим объектом, то можно вернуть this в качестве итератора:

'use strict';


let range = { from: 1,


to: 5,
[Symbol.iterator]() { return this;
},
next() {
if (this.current === undefined) {
// инициализация состояния итерации this.current = this.from;
}

if (this.current <= this.to) { return {


done: false,
value: this.current++
};
} else {
// очистка текущей итерации delete this.current;
return { done: true
};
}
}

};


for (let num of range) {
alert(num); // 1, затем 2, 3, 4, 5
}

// Произойдёт вызов Math.max(1,2,3,4,5); alert( Math.max(...range) ); // 5 (*)


При таком подходе сам объект и хранит состояние итерации (текущий перебираемый элемент).


В данном случае это работает, но для большей гибкости и понятности кода рекомендуется, всё же, выделять итератор в отдельный объект со своим состоянием и кодом.







Download 9,9 Mb.

Do'stlaringiz bilan baham:
1   ...   267   268   269   270   271   272   273   274   ...   349




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish