1. Origen e importancia
Javascript
Indicando "set" estructura de datos, principalmente Array
, Object
, Map
, Set
conjuntos de cuatro de datos, además, también puede combinar con otra entre ellas, por ejemplo Array
los miembros Map
, Map
los miembros Object
y similares. Por lo tanto Javascript
, se necesita un mecanismo de interfaz unificada para manejar todas las diferentes estructuras de datos.
El iterador ( Iterator
) es un mecanismo de este tipo. Es una interfaz que puede proporcionar un mecanismo de acceso (interfaz de acceso) para varias estructuras de datos.Cualquier Iterator
interfaz de implementación de estructura de datos puede completar la operación transversal del deconstructor de datos (la interfaz Iterator es principalmente para for...of
uso).
En segundo lugar, el proceso de implementación específico
Iterator
El proceso transversal:
- Cree un objeto puntero que apunte a la posición inicial de la deconstrucción de datos.
- El método del objeto puntero se llama por primera vez
next()
y el puntero apunta al primer miembro de la estructura de datos. - La segunda llamada al
next()
método del objeto puntero , el puntero apunta al segundo miembro de la estructura de datos. - Llame al
next()
método del objeto puntero hasta que apunte al final de la estructura de datos. (Similar a la lista vinculada en lenguaje C)
Cada vez next
que se llama al método, se devuelve la información del miembro apuntado por el puntero en la estructura de datos. Esta información es un objeto, que contiene objetos value
con done
dos atributos { value: something , done: false }
. El value
atributo es el valor del miembro actual y el done
atributo es un valor booleano, que indica si el recorrido ha terminado ( done:false
: indica que el bucle aún no ha terminado ,: done:true
indica que el ciclo ha terminado).
next
Ejemplos de valores de retorno del método de simulación :
El siguiente código define una makeIterator
función, es una función de generación de traverser, la función es devolver un objeto de traverser. ['前端','收割','机']
La ejecución de esta función en una matriz devolverá el objeto iterador (objeto puntero) de la matriz goodjob
.
var goodjob = makeIterator(['前端','收割','机'])
function makeIterator(array){
var Index = 0;//形成闭包保存指针指向位置index,通过三元表达式返回当前信息对象。
return {
next: function(){
return Index < array.length ? {
value: array[index], done: false} :
{
value: undefined, done: true};
}
}
}
goodjob.next()// {value: '前端', done: false}
goodjob.next()// {value: '收割', done: false}
goodjob.next()// {value: '机', done: false}
goodjob.next()// {value: undefined, done: false}
Dado que Iterator
solo las especificaciones de la interfaz se agregan a la estructura de datos anterior, por lo tanto, atraviesa la estructura de datos con la que se atraviesa, físicamente separada, no puede atravesar el objeto correspondiente a la estructura de datos de escritura, u objeto con la travesía Simular la estructura de datos.
Tres, la estructura de datos con la interfaz Iterator predeterminada
Iterator
Interfaz de propósito para todas las estructuras de datos que proporciona un mecanismo de acceso unificado, cuando for...of
el tiempo pasa por algún tipo de estructura de datos, el ciclo buscará automáticamente Iterator
la interfaz.
Por lo tanto, cuando una determinada estructura de datos tiene una Iterator
interfaz, significa que la estructura de datos es transitable ( iterable
).
La Iterator
interfaz predeterminada que se implementará en la estructura de datos de la Symbol.iterator
propiedad, o que tiene una estructura de datos siempre que la Symbol.iterator
propiedad pueda considerarse "atravesada" ( iterable
). Symbol.iterator
El atributo en sí es una función, que es la función generadora de travesía predeterminada de la estructura de datos actual. La ejecución de esta función devolverá un iterador. En cuanto al nombre del atributo Symbol.iterator
, es una expresión que devuelve Symbol
un objeto de iterator
propiedad, que es un tipo predefinido que tiene Symbol
un valor especial, debe colocarse entre corchetes.
const object1 = {
[Symbol.iterator] : function () {
return {
next: function () {
return {
value: 1,
done: true
};
}
};
}
};
Los objetos se object1
pueden atravesar ( iterable
) porque tienen Symbol.iterator
atributos. La ejecución de esta propiedad devolverá un objeto iterador. La característica fundamental de este objeto es su next
método. Cada vez next
que se llama al método, se devolverá un objeto de información que representa al miembro actual, con dos atributos value
y una suma done
.
Cualquier Symbol.iterator
estructura de datos con atributos implementados se denomina interfaz de travesía implementada. Llamar a esta interfaz devolverá un objeto de desplazamiento. Es decir, se puede for...of
recorrer en bucle sin ningún procesamiento .
Estructura de datos nativa con interfaz Iterator:
- Formación
- Mapa
- Conjunto
- Cuerda
- TypedArray
- Objeto NodeList
- Los argumentos objeto de la función
Symbol.iterator
Atributos de la matriz :
let arr = ['前端', '收割', '机'];
let iterator = arr[Symbol.iterator](); //因为arr中属性Symbol.iterator返回的是一个函数,
//所以在[Symbol.iterator]后面添加(),使函数执行,返回一个遍历器对象
iterator.next() // { value: '前端', done: false }
iterator.next() // { value: '收割', done: false }
iterator.next() // { value: '机', done: false }
iterator.next() // { value: undefined, done: true }
Iterador de matriz generado al for of
llamar a la iterator
interfaz
const arr = ['前端', '收割', '机'];
for(let v of arr) {
console.log(v); // 前端 收割 机
}
Map traverser generado for of
llamando a la iterator
interfaz
var handsome = new Map();
es6.set("GuangHui", "1handsome");
es6.set("JiaHao", "2handsome");
es6.set("NingDong", 666);
for (var [name, value] of es6) {
console.log(name + ": " + value);
}
// GuangHui: 1handsome
// JiaHao: 2handsome
// NingDong: 666
Establecer iterador generado al for of
llamar a la iterator
interfaz
var handsome = new Set(["GuangHui", "JiaHao", "NingDong"]);
for (var boy of handsome) {
console.log(boy);
}
// GuangHui
// JiaHao
// NingDong
El iterador generado al for of
llamar a la iterator
interfaz de un objeto similar a una matriz
// 字符串
let str = "前端收割机";
for (let s of str) {
console.log(s); // 前 端 收 割 机
}
// DOM NodeList对象
let paras = document.querySelectorAll("p");
for (let p of paras) {
p.classList.add("前端收割机");
}
// arguments对象
function printArgs() {
for (let x of arguments) {
console.log(x);
}
}
printArgs('前端', '收割机');
// '前端'
// '收割机'
Para Iterator
las estructuras de datos (principalmente objetos) que no tienen interfaces, deben Symbol.iterator
implementarse en las propiedades mismas para que puedan for...of
atravesarse en un bucle.
Causa: Object ( Object
) no es una razón por la cual las Iterator
interfaces de implementación predeterminadas , debido a las cuales atraviesan las propiedades del objeto primero, después de lo cual atravesar la propiedad es incierta, los desarrolladores deben especificar manualmente. Básicamente, el traverser es un proceso lineal. Para cualquier estructura de datos no lineal, implementar la interfaz del traverser es equivalente a implementar una transformación lineal.
Aquí el objeto se agrega como Iterator
ejemplo de la interfaz:
let object2 = {
data: [ '前端', '收割','机'],
[Symbol.iterator]() {
const self = this; //将this指向赋予self
let index = 0; //初始遍历下标
return {
next() {
if (index < self.data.length) {
return {
value: self.data[index++], //每次调用,遍历下标自增1
done: false
};
} else {
return { value: undefined, done: true }; //遍历结束返回该对象
}
}
};
}
};
Para los objetos tipo matriz (las claves y los valores existen length
atributos), la interfaz Iterator desplegada, existe un método simple, es Symbol.iterator
el método de referencia directa a la Iterator
interfaz de la matriz .
let object3 = {
0: '前端',
1: '收割',
2: '机',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator] //直接引用数组构造函数prototype中的 Symbol.iterator属性
};
for (let item of iterable) {
console.log(item); // '前端', '收割', '机'
}
Tenga en cuenta que el Symbol.iterator
método de implementar una estructura de datos específica para objetos ordinarios no tiene ningún efecto. Por ejemplo, el Symbol.iterator
método de implementar una matriz de objetos ordinarios .
let object4 = {
//该对象不存在数值键名
a: '前端',
b: '收割',
c: '机',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // undefined, undefined, undefined
}
Si el Symbol.iterator
método no corresponde a una función de generación de recorrido (es decir, devuelve un objeto de recorrido), el motor de interpretación informará un error.
var object5 = {};
obj[Symbol.iterator] = () => '前端收割机'; //返回的是一个字符串
[...object5] // TypeError: [] is not a function
Cuarto, la ocasión de llamar a la interfaz Iterator
Además del for...of
reciclaje, algunas escenas serán llamadas por Iterator
interfaces predeterminadas (es decir, Symbol.iterator
método)
Cesión de desestructuración
let set = new Set().add('前端').add('收割').add('机'); //Set通过add方法进行链式添加值
let [one,two] = set;
// x='前端'; y='收割'
let [one, ...two] = set;
// one='前端'; two=['收割','机'];
Operador de propagación
// 例一
var str = '前端收割机';
[...str] // ['前','端','收','割','机']
// 例二
let arr = ['是', '靓'];
['我', ...arr, '仔']
// ['我', '是', '靓', '仔']
El operador interno extendido llama a la Iterator
interfaz, que proporciona un mecanismo simple, se puede implementar en cualquier Iterator
estructura de datos de la interfaz, extendiendo el operador en una matriz.
rendimiento*
yield*
Lo que sigue es una estructura atravesable, que llamará a la interfaz de travesía de la estructura.
let generator = function* () {
yield "我";
yield* ["是","靓","仔"];
yield "啊";
};
var iterator = generator();
iterator.next() // { value: "我", done: false }
iterator.next() // { value: "是", done: false }
iterator.next() // { value: "靓", done: false }
iterator.next() // { value: "仔", done: false }
iterator.next() // { value: "啊", done: false }
iterator.next() // { value: undefined, done: true }
Matriz. De ()
Array.from()
Ingrese el valor de la función en forma de matriz, y la Array.from()
función llama a la interfaz Iterator para convertir la matriz de entrada en una matriz
let arrayLike = {
0: '前端',
1: '收割',
2: '机',
3: ['GuangHui','JiaHao','NingDong'],
'length': 4
}
let arr = Array.from(arrayLike)
console.log(arr) // ['前端','收割','机',['GuangHui','JiaHao','NingDong']]
Mapa (), Conjunto (), WeakMap (), WeakSet ()
Map
Introduzca pares clave-valor en el constructor en forma de matriz. Al crear un Map
objeto, el constructor de mapas llama a la Iterator
interfaz, recorre y guarda los pares clave-valor
var goodJob = new Map([['前端',1],['收割机',2]])
Promise.all ()
Promise.all()
Ingrese el valor en forma de una matriz Promise a la función, y la Promise.all()
función llama a la interfaz Iterator para atravesar y ejecutar la solicitud de promesa.
const p = Promise.all([p1, p2, p3]);
Promise.all()
Método acepta una matriz como un parámetro p1
, p2
, p3
es Promise
un ejemplo, si no, será primero llamar a los Promise.resolve
parámetros del método en el Promise
ejemplo, y luego su posterior procesamiento. Además, los Promise.all()
parámetros del método pueden no ser una matriz, pero debe tener Iterator
una interfaz y cada miembro se devuelve como Promise
instancia.
Promise.race ()
Promise.race()
Ingrese el valor en forma de una matriz Promise a la función, y la Promise.race()
función llama a la interfaz Iterator para atravesar y ejecutar la solicitud de promesa.
const p = Promise.race([p1, p2, p3]);
Promise.race()
Método acepta una matriz como un parámetro p1
, p2
, p3
es Promise
un ejemplo, si no, será primero llamar a los Promise.resolve
parámetros del método en el Promise
ejemplo, y luego su posterior procesamiento. Además, los Promise.race()
parámetros del método pueden no ser una matriz, pero debe tener Iterator
una interfaz y cada miembro se devuelve como Promise
instancia.
Agregado: interfaz de Generator
función y Iterator
relación:
El Symbol.iterator
método del objeto es igual a la función de generación de traverser del objeto, y llamar a esta función devolverá un objeto de traverser del objeto. Dado que la función Generator es la función generadora del traverser, el Generator puede asignarse a las Symbol.iterator
propiedades del objeto, de modo que el objeto tenga la interfaz Iterator.
Cinco, resumen
- El iterador (
Iterator
) puede proporcionar un mecanismo de acceso (interfaz de acceso) para varias estructuras de datos. CualquierIterator
interfaz de implementación de estructura de datos puede completar la operación transversal del deconstructor de datos (la interfaz Iterator es principalmente parafor...of
uso). Iterator
El proceso transversal: crea un objeto puntero que apunta a la posición inicial de la deconstrucción de datos. Elnext()
método del objeto puntero se llama continuamente y el puntero se mueve hacia atrás hasta que apunta al final de la estructura de datos. Cada veznext
que se llama al método, se devuelve la información del miembro apuntado por el puntero en la estructura de datos{ value: something , done: false }
.Array
,Map
,Set
,String
,TypedArray
,NodeLis
Objetos T, función dearguments
los objetos en nativo incluyeIterator
una estructura de datos de la interfaz.- Llamada
Iterator
ocasiones interfaz:for...of
ciclo, la asignación desestructurada, la expansión deyield*
los operadores,Array.from()
,Map()
,Set()
,WeakMap()
,WeakSet()
,Promise.all()
,Promise.race()
,.