Что такое итератор?
удовлетворитьпротокол итератораОбъект.
протокол итератора:
объектnext
Метод - это функция без аргументов, которая возвращает объект, который имеетdone
а такжеvalue
Два свойства:
-
done
(boolean
):- если итератор прошел итерируемую последовательность
true
. В настоящее времяvalue
может описывать возвращаемое значение этого итератора. - Если итератор может дать следующее значение в последовательности, то
false
.这等效于连同done
Свойства также не указаны.
- если итератор прошел итерируемую последовательность
-
value
: любое значение JavaScript, возвращаемое итератором.done
дляtrue
можно опустить.
ES5 реализует простой итератор:
function createIterator(items) {
var i = 0;
return {
next: function() {
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
};
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: 2, done: false }"
console.log(iterator.next()); // "{ value: 3, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
// 之后的所有调用
console.log(iterator.next()); // "{ value: undefined, done: true }"
Что такое итерируемый объект (Iterable)?
удовлетворитьИтерируемый протоколОбъект является итерируемым объектом.
Итерируемый протокол:
объект[Symbol.iterator]
value — это функция без параметров, которая возвращает итератор.
В ES6 все объекты коллекции (Array
,Set
а такжеMap
)так же какString
,arguments
Оба являются итерируемыми объектами, и все они имеют итераторы по умолчанию.
Итерируемые объекты могут использоваться в следующих операторах:
for (let value of ['a', 'b', 'c']) {
console.log(value);
}
// "a"
// "b"
// "c"
[...'abc']; // ["a", "b", "c"]
console.log(...['a', 'b', 'c']); // ["a", "b", "c"]
function* gen() {
yield* ['a', 'b', 'c'];
}
gen().next(); // { value: "a", done: false }
let [a, b, c] = new Set(['a', 'b', 'c']);
a; // 'a'
пониматьfor...ofцикл
for...of
Принимает Iterable или значение, которое может быть приведено/обернуто в Iterable (например, 'abc'). При обходе,for...of
получит итерируемый объект[Symbol.iterator]()
, вызовите next() для итератора последовательно, пока итератор не вернет значение объекта.done
собственностьtrue
Когда обход заканчивается, значение не обрабатывается.
for...of
Пример цикла:
var a = ["a","b","c","d","e"];
for (var val of a) {
console.log( val );
}
// "a" "b" "c" "d" "e"
Например, преобразуется в общую петлю, эквивалентно вышеуказанномуfor...of
цикл:
var a = ["a","b","c","d","e"];
for (var val, ret, it = a[Symbol.iterator]();
(ret = it.next()) && !ret.done;
) {
val = ret.value;
console.log( val );
}
// "a" "b" "c" "d" "e"
сделать итератор итерируемым
существуетчто такое итераторраздел, мы настраиваем простую функцию, которая генерирует итераторcreateIterator
, но итератор, сгенерированный этой функцией, не реализует итерируемый протокол, поэтому его нельзя использовать вfor...of
И т.д., используемые в грамматике. Это может быть достигнуто протоколом итерации для объекта, в[Symbol.iterator]
Функция возвращает сам итератор.
function createIterator(items) {
var i = 0;
return {
next: function () {
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
},
[Symbol.iterator]: function () { return this }
};
}
var iterator = createIterator([1, 2, 3]);
console.log(...iterator)
Что такое генератор (генератор)?
генераторная функция
Генераторная функция (GeneratorFunction)способен вернутьГенератор (Генератор)Функция.生成器函数由放在 function 关键字之后的一个星号( * )来表示,并能使用新的 yield 关键字。
function *aGeneratorfunction(){
yield 1
yield 2
yield 3
};
var aGeneratorObject = aGeneratorfunction()
// 生成器对象
aGeneratorObject.toString() // "[object Generator]"
Объекты Builder являются как итераторы и итеративные объекты
function *aGeneratorfunction(){
yield 1
yield 2
yield 3
};
var aGeneratorObject = aGeneratorfunction()
// 满足迭代器协议,是迭代器
aGeneratorObject.next() // {value: 1, done: false}
aGeneratorObject.next() // {value: 2, done: false}
aGeneratorObject.next() // {value: 3, done: false}
aGeneratorObject.next() // {value: undefined, done: true}
// [Symbol.iterator]是一个无参函数,该函数执行后返回生成器对象本身(是迭代器),所以是可迭代对象
aGeneratorObject[Symbol.iterator]() === aGeneratorObject // true
// 可以被迭代
var aGeneratorObject1 = aGeneratorfunction()
[...aGeneratorObject1] // [1, 2, 3]
Взамен Строитель
перебрать возвращаемый объектdone
значениеtrue
Итерация заканчивается, когдаvalue
иметь дело с.
function *createIterator() {
yield 1;
return 42;
yield 2;
}
let iterator = createIterator();
iterator.next(); // {value: 1, done: false}
iterator.next(); // {value: 42, done: true}
iterator.next(); // {value: undefined, done: true}
done
Когда значение истинно, итерация завершается, и итерация не обрабатывает значение. Таким образом, для этого обхода итератора значение 42 не будет обработано.
let iterator1 = createIterator();
console.log(...iterator); // 1
Добавить к[Symbol.iterator]
СделатьObject
повторяемый
согласно сИтерируемый протокол,ДатьObject
Добавлен прототип[Symbol.iterator]
Нет возвращаемого значения - это эталонная функция объекта, объект возвращается соответствие протокола итератора.
Object.prototype[Symbol.iterator] = function () {
var i = 0
var items = Object.entries(this)
return {
next: function () {
var done = (i >= items.length);
var value = !done ? items[i++] : undefined;
return {
done: done,
value: value
};
}
}
}
var a = {
name: 'Jimmy',
age: 18,
job: 'actor'
}
console.log(...a) // [ 'name', 'Jimmy' ] [ 'age', 18 ] [ 'job', 'actor' ]
Упростите свой код с помощью генераторов:
Object.prototype[Symbol.iterator] = function* () {
for (const key in this) {
if (this.hasOwnProperty(key)) {
yield [key, this[key]];
}
}
}
var a = {
name: 'Jimmy',
age: 18,
job: 'actor'
}
console.log(...a) // [ 'name', 'Jimmy' ] [ 'age', 18 ] [ 'job', 'actor' ]
делегат генератораyield*
function* g1() {
yield 1;
yield 2;
}
function* g2() {
yield* g1();
yield* [3, 4];
yield* "56";
yield* arguments;
}
var generator = g2(7, 8);
console.log(...generator); // 1 2 3 4 "5" "6" 7 8
последний пример
Проанализируйте следующий код:
function* fibs() {
var a = 0;
var b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(first, second, third, fourth, fifth, sixth);
В этом кодеfibs
генератор, генерирующий бесконечно длинные последовательности Фибоначчи,[a, b] = [b, a + b]
Это назначение обмена назначения реструктуризации (= присвоение рассчитывается справа налево, поэтому сначала вычислите правую сторону.a+b
, а затем структура, каждая из которых имеет эффект назначения обмена), написанная на ES5 для создания массива конечной длины следующим образом:
function fibs1(n) {
var a = 0;
var b = 1;
var c = 0;
var result = []
for (var i = 0; i < n; i++) {
result.push(a);
c = a;
a = b;
b = c + b;
}
return result;
}
console.log(fibs1(6)) // [0, 1, 1, 2, 3, 5]
И в первом фрагменте кода изfibs()
Первые шесть значений деконструируются из итератора (генератор — это подмножество итератора), пример кода следующий:
function* fibs2(n) {
var a = 0;
var b = 1;
for (var i = 0; i < n; i++) {
yield a;
[a, b] = [b, a + b];
}
}
console.log(...fibs2(6))
Зачем использовать итераторы, генераторы и каковы преимущества?
...пока не разобрался
Выше есть много частей, которые я понимаю лично, добро пожаловать на исправление ошибок (* ̄︶ ̄)
Ссылаться на: