Conceptos básicos de JavaScript: concepto y uso del iterador

Inserte la descripción de la imagen aquí

1. Origen e importancia

JavascriptIndicando "set" estructura de datos, principalmente Array, Object, Map, Setconjuntos de cuatro de datos, además, también puede combinar con otra entre ellas, por ejemplo Arraylos miembros Map, Maplos miembros Objecty 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 Iteratorinterfaz de implementación de estructura de datos puede completar la operación transversal del deconstructor de datos (la interfaz Iterator es principalmente para for...ofuso).

En segundo lugar, el proceso de implementación específico

IteratorEl proceso transversal:

  1. Cree un objeto puntero que apunte a la posición inicial de la deconstrucción de datos.
  2. El método del objeto puntero se llama por primera vez next()y el puntero apunta al primer miembro de la estructura de datos.
  3. La segunda llamada al next()método del objeto puntero , el puntero apunta al segundo miembro de la estructura de datos.
  4. 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 nextque 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 valuecon donedos atributos { value: something , done: false }. El valueatributo es el valor del miembro actual y el doneatributo es un valor booleano, que indica si el recorrido ha terminado ( done:false: indica que el bucle aún no ha terminado ,: done:trueindica que el ciclo ha terminado).

nextEjemplos de valores de retorno del método de simulación :

El siguiente código define una makeIteratorfunció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 Iteratorsolo 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

IteratorInterfaz de propósito para todas las estructuras de datos que proporciona un mecanismo de acceso unificado, cuando for...ofel tiempo pasa por algún tipo de estructura de datos, el ciclo buscará automáticamente Iteratorla interfaz.

Por lo tanto, cuando una determinada estructura de datos tiene una Iteratorinterfaz, significa que la estructura de datos es transitable ( iterable).

La Iteratorinterfaz predeterminada que se implementará en la estructura de datos de la Symbol.iteratorpropiedad, o que tiene una estructura de datos siempre que la Symbol.iteratorpropiedad pueda considerarse "atravesada" ( iterable). Symbol.iteratorEl 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 Symbolun objeto de iteratorpropiedad, que es un tipo predefinido que tiene Symbolun valor especial, debe colocarse entre corchetes.

const object1 = {
  [Symbol.iterator] : function () {
    return {
      next: function () {
        return {
          value: 1,
          done: true
        };
      }
    };
  }
};

Los objetos se object1pueden atravesar ( iterable) porque tienen Symbol.iteratoratributos. La ejecución de esta propiedad devolverá un objeto iterador. La característica fundamental de este objeto es su nextmétodo. Cada vez nextque se llama al método, se devolverá un objeto de información que representa al miembro actual, con dos atributos valuey una suma done.

Cualquier Symbol.iteratorestructura 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...ofrecorrer 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.iteratorAtributos 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 ofllamar a la iteratorinterfaz

const arr = ['前端', '收割', '机'];

for(let v of arr) {
  console.log(v); // 前端 收割 机
}

Map traverser generado for ofllamando a la iteratorinterfaz

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 ofllamar a la iteratorinterfaz

var handsome = new Set(["GuangHui", "JiaHao", "NingDong"]);
for (var boy of handsome) {
  console.log(boy);
}
// GuangHui
// JiaHao
// NingDong

El iterador generado al for ofllamar a la iteratorinterfaz 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 Iteratorlas estructuras de datos (principalmente objetos) que no tienen interfaces, deben Symbol.iteratorimplementarse en las propiedades mismas para que puedan for...ofatravesarse en un bucle.

Causa: Object ( Object) no es una razón por la cual las Iteratorinterfaces 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 Iteratorejemplo 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 lengthatributos), la interfaz Iterator desplegada, existe un método simple, es Symbol.iteratorel método de referencia directa a la Iteratorinterfaz 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.iteratormétodo de implementar una estructura de datos específica para objetos ordinarios no tiene ningún efecto. Por ejemplo, el Symbol.iteratormé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.iteratormé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...ofreciclaje, algunas escenas serán llamadas por Iteratorinterfaces predeterminadas (es decir, Symbol.iteratormé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 Iteratorinterfaz, que proporciona un mecanismo simple, se puede implementar en cualquier Iteratorestructura 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 ()

MapIntroduzca pares clave-valor en el constructor en forma de matriz. Al crear un Mapobjeto, el constructor de mapas llama a la Iteratorinterfaz, 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, p3es Promiseun ejemplo, si no, será primero llamar a los Promise.resolveparámetros del método en el Promiseejemplo, y luego su posterior procesamiento. Además, los Promise.all()parámetros del método pueden no ser una matriz, pero debe tener Iteratoruna interfaz y cada miembro se devuelve como Promiseinstancia.

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, p3es Promiseun ejemplo, si no, será primero llamar a los Promise.resolveparámetros del método en el Promiseejemplo, y luego su posterior procesamiento. Además, los Promise.race()parámetros del método pueden no ser una matriz, pero debe tener Iteratoruna interfaz y cada miembro se devuelve como Promiseinstancia.

Agregado: interfaz de Generatorfunción y Iteratorrelación:

El Symbol.iteratormé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.iteratorpropiedades del objeto, de modo que el objeto tenga la interfaz Iterator.

Cinco, resumen

  1. El iterador ( Iterator) puede proporcionar un mecanismo de acceso (interfaz de acceso) para varias estructuras de datos. Cualquier Iteratorinterfaz de implementación de estructura de datos puede completar la operación transversal del deconstructor de datos (la interfaz Iterator es principalmente para for...ofuso).
  2. IteratorEl proceso transversal: crea un objeto puntero que apunta a la posición inicial de la deconstrucción de datos. El next()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 vez nextque 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 }.
  3. Array, Map, Set, String, TypedArray, NodeLisObjetos T, función de argumentslos objetos en nativo incluye Iteratoruna estructura de datos de la interfaz.
  4. Llamada Iteratorocasiones interfaz: for...ofciclo, la asignación desestructurada, la expansión de yield*los operadores, Array.from(), Map(), Set(), WeakMap(), WeakSet(), Promise.all(), Promise.race(),.

Supongo que te gusta

Origin blog.csdn.net/imagine_tion/article/details/113119415
Recomendado
Clasificación