"Standard ES6 Getting Started" (Ruan Yifeng) - 17.Iterator y para ... de bucle

El concepto 1.Iterator (Walker) de

JavaScript medios originales "una colección de" estructuras de datos, principalmente array ( Array) y objetos ( Object), ha añadido un ES6 Mapy Set. Así que hay un conjunto de cuatro datos, los usuarios también pueden usarlas en combinación, definir sus propias estructuras de datos, tales como miembros de la matriz es Map, Maplos miembros del objeto. Esto requiere un mecanismo de interfaz unificada para hacer frente a todas las diferentes estructuras de datos.

Iterator (Iterador) es uno de tales mecanismos. Es una interfaz que proporciona un mecanismo unificado para acceder a una variedad de diferentes estructuras de datos. Cualquier estructura de datos siempre que la interfaz Iterator despliegue, a la operación completa de recorrido (es decir, procesa secuencialmente todos los miembros de la estructura de datos).

Iterador papel tiene tres: uno para las diversas estructuras de datos, para proporcionar una interfaz fácil acceso unificado, en segundo lugar es hacer que los miembros de la estructura de datos pueden ser dispuestos en un cierto orden, y el tercero se ES6 crear un nuevo movimiento de desplazamiento for...ofciclo , interfaz iterador es principalmente para for...ofel consumo.

Iterador de recorrido es esto.

(1) Crear un puntero al objeto , puntos a la posición inicial de la estructura de datos actual. Es decir, de la naturaleza objeto Walker, es un puntero al objeto.

(2) el primer puntero de objeto llamada nextmétodo, la primera puntero a un miembro de estructura de datos.

(3) un segundo puntero a la llamada de objeto nextmétodo, un puntero apunta a una estructura de datos del segundo miembro.

(4) continúa para llamar al puntero de objeto nextmétodo, la posición final hasta que apunte a la estructura de datos.

Cada llamada nextmétodo, devolverá información acerca de los miembros actuales de la estructura de datos. Específicamente, es un retorno contiene valuey doneel objeto dos propiedades. Donde valuela propiedad es el valor del miembro actual, donees un valor booleano que indica si el final de la poligonal.

La siguiente es una simulación de nextejemplo de un valor de retorno método.

var it = makeIterator(['a', 'b']);

it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++], done: false} :
        {value: undefined, done: true};
    }
  };
}

El código anterior define una makeIteratorfunción, se genera una función de recorrido, simplemente envía un objeto de visitante. Matriz de ['a', 'b']aplicación de esta función devolverá el objeto a atravesar la matriz (es decir, el puntero del objeto) it.

Puntero al objeto nextun método para mover el puntero. Inicialmente, el puntero al comienzo de la matriz. Entonces, cada llamada nextal método, el puntero que apunte al siguiente miembro de la matriz. La primera llamada, punto a; la segunda llamada, apunta b.

nextEl método devuelve un objeto que representa información sobre los miembros de datos actuales. Este objeto tiene valuey donedos propiedades, valueretornos de propiedad un miembro de la posición actual, donees un valor booleano que indica si el final de la poligonal, si eso es aún necesario llamar de nuevo nextmétodo.

En resumen, el puntero a la llamada a un objeto nextmétodo, se puede dar por adelantado para atravesar la estructura de datos.

Para los objetos de Walker, done: falsey value: undefinedse omiten los atributos, por lo que la anterior makeIteratorfunción puede ser simplificado en el siguiente formulario.

function makeIterator(array) {
  var nextIndex = 0;
  return {
    next: function() {
      return nextIndex < array.length ?
        {value: array[nextIndex++]} :
        {done: true};
    }
  };
}

Puesto que solamente se añade el estándar de interfaz Iterator a la estructura de datos anterior, por lo tanto, que atraviesan la estructura de datos con la que se recorre, físicamente separadas, se puede escribir los datos correspondientes no atravesar la estructura del objeto, con un andador o simulación de una estructura de datos del objeto. El siguiente es un objeto infinito atravesar ejemplo correr.

var it = idMaker();

it.next().value // 0
it.next().value // 1
it.next().value // 2
// ...

function idMaker() {
  var index = 0;

  return {
    next: function() {
      return {value: index++, done: false};
    }
  };
}

En el ejemplo anterior, se genera la función de recorrido idMaker, devuelve un objeto visitante (es decir, el puntero del objeto). Sin embargo, no estructuras de datos correspondiente, o que, atravesando el objeto mismo describe una estructura de datos a cabo.

Si mecanografiado texto, interfaz de recorrido (la Iterable), el objeto puntero (el iterador) y los nextdevuelve el método los valores de las especificaciones se pueden describir como sigue.

interface Iterable {
  [Symbol.iterator]() : Iterator,
}

interface Iterator {
  next(value?: any) : IterationResult,
}

interface IterationResult {
  value: any,
  done: boolean,
}

2. Por defecto iterador interfaz

Iterator interfaz propósito, todas las estructuras de datos es proporcionar un mecanismo de acceso unificada, es decir, for...ofel ciclo (ver abajo). Cuando for...ofel bucle de una cierta estructura de datos de recorrido, el ciclo buscará automáticamente la interfaz Iterator.

Una estructura de datos, siempre que el despliegue de la interfaz Iterator, llamamos a esta estructura de datos es un "transitable" (iterable).

ES6 especificado, la interfaz Iterator defecto desplegada en la estructura de datos de la Symbol.iteratorpropiedad, o que tiene una estructura de datos siempre que la Symbol.iteratorpropiedad puede ser considerada para ser "atravesado" (iterable). Symbol.iteratorAtributo es en sí mismo una función de la estructura de datos actual es atravesada para generar la función predeterminada. La implementació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 de valor especial de símbolos, que deben colocarse entre corchetes (véase el capítulo "Símbolo").

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

El código anterior, el objeto objes desplazable (Iterable), debido a que tiene Symbol.iteratorpropiedades. La implementación de esta propiedad, se devolverá un objeto visitante. La característica fundamental del objeto es tener un nextmétodo. Cada llamada nextmétodo devuelve un objeto de información representa los miembros actuales, con valuey donedos propiedades.

Algunos de la estructura de datos incluye una interfaz nativa ES6 Iterator (tales como matrices), es decir, sin ningún tratamiento, puede ser for...ofbucle a través. La razón es que estas estructuras de datos desplegados nativos Symbol.iteratorpropiedades (véase más adelante), algunas otras estructuras de datos no son (como objeto). Los que despliega Symbol.iteratorla estructura de datos de atributos, llamado el despliegue de una interfaz de recorrido. Llame a esta interfaz, devolverá un objeto visitante.

estructura de datos Native incluye la siguiente interfaz iterador.

  • Formación
  • Mapa
  • Conjunto
  • Cuerda
  • TypedArray
  • función de argumentos objeto
  • objeto NodeList

El siguiente ejemplo es una serie de Symbol.iteratorpropiedades.

let arr = ['a', 'b', 'c'];
let iter = arr[Symbol.iterator]();

iter.next() // { value: 'a', done: false }
iter.next() // { value: 'b', done: false }
iter.next() // { value: 'c', done: false }
iter.next() // { value: undefined, done: true }

El código anterior, la variable arres una matriz, después de haber atravesado la interfaz original regalado desplegado en arrlas Symbol.iteratorpropiedades anteriores. Por lo tanto, llamar a esta propiedad, se obtiene un objeto visitante.

Para nativa estructura de datos de implementación de interfaz Iterator, no escriba su propia función de generación de Walker, for...ofel ciclo recorrerá automáticamente. Además, otras estructuras de datos (principalmente de objetos) de la interfaz Iterator, se necesita poseer la Symbol.iteratorpropiedad por encima de la implementación, este será for...ofun bucle a través.

Objeto (Object) hay ninguna razón por la interfaz Iterator implantación por defecto, lo que se debe a las propiedades del objeto primer recorrido, después de lo cual atraviesan la propiedad es incierto, los desarrolladores tienen que especificar manualmente. Esencialmente, el caminante es un proceso lineal, para cualquier estructura no lineal de datos, atravesando la interfaz de despliegue, es equivalente a la conversión de un despliegue lineal. Sin embargo, en sentido estricto, el objeto que atraviesa la interfaz de despliegue no es muy necesario, porque cuando un objeto en realidad está utilizando la estructura como un mapa, ES5 Mapa ninguna estructura, y ofertas nativos ES6.

Si un objeto puede ser proporcionada a for...ofla interfaz Iterator llamado bucle debe estar en Symbol.iteratorel método de implementación de atravesar propiedad generada (objeto prototipo El método también puede tener la cadena).

class RangeIterator {
  constructor(start, stop) {
    this.value = start;
    this.stop = stop;
  }

  [Symbol.iterator]() { return this; }

  next() {
    var value = this.value;
    if (value < this.stop) {
      this.value++;
      return {done: false, value: value};
    }
    return {done: true, value: undefined};
  }
}

function range(start, stop) {
  return new RangeIterator(start, stop);
}

for (var value of range(0, 3)) {
  console.log(value); // 0, 1, 2
}

Los códigos anteriores son una implementación de la interfaz Iterator clase escrita. Symbol.iteratorAtributo corresponde a una función que devuelve el objeto actual de desplazamiento objetos después de la ejecución.

Los siguientes son ejemplos realizados por un puntero a una estructura andador.

function Obj(value) {
  this.value = value;
  this.next = null;
}

Obj.prototype[Symbol.iterator] = function() {
  var iterator = { next: next };

  var current = this;

  function next() {
    if (current) {
      var value = current.value;
      current = current.next;
      return { done: false, value: value };
    } else {
      return { done: true };
    }
  }
  return iterator;
}

var one = new Obj(1);
var two = new Obj(2);
var three = new Obj(3);

one.next = two;
two.next = three;

for (var i of one){
  console.log(i); // 1, 2, 3
}

El código anterior se despliega por primera vez en la cadena de prototipo constructor Symbol.iteratorllamada de método que devuelve un objeto visitante iterator, llame del objeto nextmétodos, mientras que un valor de retorno, el puntero interno automático a la siguiente instancia.

Aquí hay otro objeto para añadir a los ejemplos de interfaz Iterator.

let obj = {
  data: [ 'hello', 'world' ],
  [Symbol.iterator]() {
    const self = this;
    let index = 0;
    return {
      next() {
        if (index < self.data.length) {
          return {
            value: self.data[index++],
            done: false
          };
        } else {
          return { value: undefined, done: true };
        }
      }
    };
  }
};

Para array-como objetos (claves y valores existen lengthatributos), interfaz Iterator desplegado, hay un método simple, es Symbol.iteratorel método de referencia directa a una gran variedad de interfaces de iterador.

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
// 或者
NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];

[...document.querySelectorAll('div')] // 可以执行了

objeto NodeList es una matriz de objetos similares, que tiene interfaz ya atravesado directamente poligonal. El código anterior, vamos a atravesar la interfaz en su variedad de Symbol.iteratoratributos, podemos ver ningún efecto.

Aquí es otra llamada matriz-como objeto de matriz Symbol.iteratorejemplo del método.

let iterable = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3,
  [Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
  console.log(item); // 'a', 'b', 'c'
}

Tenga en cuenta que los objetos ordinarios para implementar una serie de Symbol.iteratormétodos, no hay ningún efecto.

let iterable = {
  a: 'a',
  b: 'b',
  c: '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 correspondiente no se genera la función de recorrido (es decir, devuelve un objeto iterador), se dará una explicación del motor.

var obj = {};

obj[Symbol.iterator] = () => 1;

[...obj] // TypeError: [] is not a function

El código anterior, las variables del método correspondiente no se genera la función de recorrido, se informa de un error.objSymbol.iterator

Con interfaces Walker, estructuras de datos se pueden utilizar for...ofpara recorrer (véase más adelante), también se puede utilizar whilepara recorrer.

var $iterator = ITERABLE[Symbol.iterator]();
var $result = $iterator.next();
while (!$result.done) {
  var x = $result.value;
  // ...
  $result = $iterator.next();
}

En el código anterior, ITERABLEque representa una determinada estructura de datos de recorrido, $iteratorque Traversal objeto. Cada movimiento de desplazamiento del objeto de puntero ( nextmétodos), se devuelven valor de comprobación de doneatributo, si el extremo no poligonal, el puntero se mueve al siguiente objeto visitante ( nextmétodo), ciclo continuo.

3. Llame iterador ocasión interfaz

Algunas ocasiones llaman Iterator interfaz por defecto (es decir, Symbol.iteratormétodo), se introducirá la siguiente además de la for...ofciclo, hay varias otras ocasiones.

(1) Asignación de deconstrucción

Cuando las matrices y estructuras deconstrucción de clasificación establecidos, llame al defecto Symbol.iteratormétodo.

let set = new Set().add('a').add('b').add('c');

let [x,y] = set;
// x='a'; y='b'

let [first, ...rest] = set;
// first='a'; rest=['b','c'];

(2) El operador Extended

ampliada (...) va a llamar a la interfaz Iterator defecto.

// 例一
var str = 'hello';
[...str] //  ['h','e','l','l','o']

// 例二
let arr = ['b', 'c'];
['a', ...arr, 'd']
// ['a', 'b', 'c', 'd']

código de operador expansión interna arriba se llama la interfaz Iterator.

De hecho, esto proporciona un mecanismo simple, se puede implementar en cualquier estructura de datos de interfaz Iterator, en una matriz. Esto es, cada vez que una estructura de datos desplegado interfaz Iterator, se puede extender utilizando el operador, que se convierte en una matriz.

let arr = [...iterable];

(3) Rendimiento *

yield*Está de vuelta con una estructura transitable, que llama el andador de la estructura de la interfaz.

let generator = function* () {
  yield 1;
  yield* [2,3,4];
  yield 5;
};

var iterator = generator();

iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: 4, done: false }
iterator.next() // { value: 5, done: false }
iterator.next() // { value: undefined, done: true }

(4) Otros ocasiones

Debido a las llamadas iterar atraviesan la interfaz, por lo que todas las ocasiones de aceptar matrices como parámetros, de hecho, están llamados a Traverse interfaz. Estos son algunos ejemplos.

  • de ... de
  • Array.from ()
  • Mapa (), Set (), WeakMap (), WeakSet () ( por ejemplo new Map([['a',1],['b',2]]))
  • Promise.all ()
  • Promise.race ()

4. cadena interfaz Iterator

Cadena es una matriz similar a objetos, que también tiene una interfaz Iterator nativo.

var someString = "hi";
typeof someString[Symbol.iterator]
// "function"

var iterator = someString[Symbol.iterator]();

iterator.next()  // { value: "h", done: false }
iterator.next()  // { value: "i", done: false }
iterator.next()  // { value: undefined, done: true }

El código anterior, la llamada Symbol.iteratordevuelve un objeto de desplazamiento, la travesía de este método siguiente se puede invocar, por el recorrido de la cadena.

Puede cubrir nativa Symbol.iteratormétodo, el propósito de modificar el comportamiento de la poligonal.

var str = new String("hi");

[...str] // ["h", "i"]

str[Symbol.iterator] = function() {
  return {
    next: function() {
      if (this._first) {
        this._first = false;
        return { value: "bye", done: false };
      } else {
        return { done: true };
      }
    },
    _first: true
  };
};

[...str] // ["bye"]
str // "hi"

En el código anterior, la cadena str Symbol.iteratormétodo es modificado, operador, de modo prolongado ( ...) Devuelve el valor se convirtió bye, y la propia cadena o hi.

Generador 5.Iterator interfaz de la función

Symbol.iteratorLa implementación más sencilla del método o el uso de la función de generador para introducir el siguiente capítulo.

let myIterable = {
  [Symbol.iterator]: function* () {
    yield 1;
    yield 2;
    yield 3;
  }
}
[...myIterable] // [1, 2, 3]

// 或者采用下面的简洁写法

let obj = {
  * [Symbol.iterator]() {
    yield 'hello';
    yield 'world';
  }
};

for (let x of obj) {
  console.log(x);
}
// "hello"
// "world"

En el código anterior, Symbol.iteratorel método casi sin desplegar cualquier código, siempre que el valor de retorno del comando dado por el rendimiento de cada paso.

6. retorno objeto visitante (), a tiro ()

Además de atravesar el objeto nextmétodo, también puede tener returnmétodos y throwmétodos. Si usted escribe su propia función de generación objeto de visitantes, que nextse va a desplegar, returnmétodos, y throwsi el método de implementación es opcional.

returnEl método de uso de la ocasión es, si las for...ofsalidas de bucle de antelación (por lo general a causa de un error, o tiene breakdeclaraciones), se llamará returnal método. Si un objeto antes de completar la travesía, es necesario limpiar o liberar recursos, puede implementar returnel método.

function readLinesSync(file) {
  return {
    [Symbol.iterator]() {
      return {
        next() {
          return { done: false };
        },
        return() {
          file.close();
          return { done: true };
        }
      };
    },
  };
}

En el código anterior, la función readLinesSyncacepta un objeto de archivo como argumento y devuelve un objeto de visitantes, que además de nextmétodo, también desplegó returnmétodo. Los dos casos siguientes activarán la ejecución returndel método.

// 情况一
for (let line of readLinesSync(fileName)) {
  console.log(line);
  break;
}

// 情况二
for (let line of readLinesSync(fileName)) {
  console.log(line);
  throw new Error();
}

En el código anterior, después de la primera línea de un caso en el que el archivo de salida, se ejecutará returnel método, cierre el archivo; Caso 2 se llevará a cabo returndespués de que el método para cerrar el archivo, a continuación, se emite un error.

Tenga en cuenta que el returnmétodo debe devolver un objeto, que está determinada por las especificaciones del generador.

throwmétodo de la función del generador se utiliza principalmente con el objeto general de atravesar menos de este método. Véase el capítulo "Generador de funciones".

7. Para la circulación de ...

Una estructura de datos, siempre que el despliegue de la Symbol.iteratorpropiedad, que se considera que tiene iterador interfaz, puede for...ofbucle a través de sus miembros. En otras palabras, for...ofel bucle interno es una estructura de datos llamada el Symbol.iteratormétodo.

for...ofRango de matrices circulantes se pueden usar incluyen, Set, y la estructura del mapa matriz similar a algunos de los objetos (tales como argumentsobjetos, objetos DOM NodeList), las cadenas de aquí en adelante objetos del generador, y el carácter.

colección

array nativo incluye iteratoruna interfaz (es decir, el despliegue predeterminado Symbol.iteratorpropiedad), for...ofes generado por esa interfaz en atravesar la naturaleza recursiva, puede ser demostrado por el siguiente código.

const arr = ['red', 'green', 'blue'];

for(let v of arr) {
  console.log(v); // red green blue
}

const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);

for(let v of obj) {
  console.log(v); // red green blue
}

En el código anterior, objeto vacío objpara desplegar una serie arrde Symbol.iteratorpropiedades, los resultados de objla for...ofciclo, y produce arrexactamente los mismos resultados.

for...ofEjemplos de matriz de bucle pueden reemplazar forEachmétodo.

const arr = ['red', 'green', 'blue'];

arr.forEach(function (element, index) {
  console.log(element); // red green blue
  console.log(index);   // 0 1 2
});

JavaScript originales for...inciclo, sólo se puede obtener materias claves no se puede obtener directamente la clave. ES6 proporcionado for...ofbucle, permitiendo que se obtiene clave de recorrido.

var arr = ['a', 'b', 'c', 'd'];

for (let a in arr) {
  console.log(a); // 0 1 2 3
}

for (let a of arr) {
  console.log(a); // a b c d
}

Los códigos anteriores indican, for...inbucle lee el nombre de la clave, for...ofclave de lectura de bucle. Si desea través de for...ofla circulación, el acceso al índice de la matriz, se puede hacer uso de la instancia de matriz entriesmétodo y el keysmétodo (ver "conjuntos ampliados" capítulo).

for...ofInterfaz de recorrido de bucle de llamada, la interfaz de recorrido devuelve una propiedad de matriz con sólo el índice numérico. Con este for...inciclo no es lo mismo.

let arr = [3, 5, 7];
arr.foo = 'hello';

for (let i in arr) {
  console.log(i); // "0", "1", "2", "foo"
}

for (let i of arr) {
  console.log(i); //  "3", "5", "7"
}

En el código anterior, for...ofel bucle no devuelve una matriz arrde foopropiedades.

Estructura del juego y mapa

Conjunto Mapa estructura nativa que tiene la interfaz Iterator, puede utilizarse como for...ofbucle.

var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
  console.log(e);
}
// Gecko
// Trident
// Webkit

var es6 = new Map();
es6.set("edition", 6);
es6.set("committee", "TC39");
es6.set("standard", "ECMA-262");
for (var [name, value] of es6) {
  console.log(name + ": " + value);
}
// edition: 6
// committee: TC39
// standard: ECMA-262

El código anterior muestra la forma de repetición estructura de conjunto y la estructura mapa. Hay dos notable, primera orden de recorrido es de acuerdo con los respectivos miembros se añaden secuencialmente en la estructura de datos. En segundo lugar, la estructura de recorrido Conjunto, devuelve un valor, mientras Mapa estructura transversal, devuelve una matriz de dos miembros de la matriz son nombres y valores de los miembros actuales del mapa de teclado.

let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
  console.log(pair);
}
// ['a', 1]
// ['b', 2]

for (let [key, value] of map) {
  console.log(key + ' : ' + value);
}
// a : 1
// b : 2

Cálculo de la estructura de datos generada

Parte de la estructura de datos se basa en la estructura de datos existente, generada computacionalmente. Por ejemplo, una matriz ES6, Set, mapa desplegar los tres métodos siguientes vuelven objeto de visitantes después de la llamada.

  • entries()Devuelve un desplazamiento objeto para atravesar [键名, 键值]una matriz de. Una matriz de valores de índice para el nombre de clave es, por Set, nombre de la clave con la misma clave. Mapa estructura de interfaz Iterator, el valor predeterminado es llamar al entriesmétodo.
  • keys() Devuelve un objeto iterador que se utiliza para atravesar todas las llaves.
  • values() Devuelve un objeto de desplazamiento para recorrer todas las claves.

Después de tres de generación de llamada método de objeto poligonal, atravesado por la estructura de datos generada se calculan.

let arr = ['a', 'b', 'c'];
for (let pair of arr.entries()) {
  console.log(pair);
}
// [0, 'a']
// [1, 'b']
// [2, 'c']

matrices similares de objetos

Matriz-como objeto comprende un número de categorías. La siguiente es for...ofreciclado para su uso en una cadena, objetos DOM NodeList, argumentsun ejemplo del objeto.

// 字符串
let str = "hello";

for (let s of str) {
  console.log(s); // h e l l o
}

// DOM NodeList对象
let paras = document.querySelectorAll("p");

for (let p of paras) {
  p.classList.add("test");
}

// arguments对象
function printArgs() {
  for (let x of arguments) {
    console.log(x);
  }
}
printArgs('a', 'b');
// 'a'
// 'b'

Para las cadenas, for...ofel ciclo no es una característica que identifique correctamente el 32 bits de caracteres UTF-16.

for (let x of 'a\uD83D\uDC0A') {
  console.log(x);
}
// 'a'
// '\uD83D\uDC0A'

No todos los objetos tienen una interfaz de matriz Iterator similares, una solución simple es utilizar el Array.frommétodo que ser convertido a una matriz.

let arrayLike = { length: 2, 0: 'a', 1: 'b' };

// 报错
for (let x of arrayLike) {
  console.log(x);
}

// 正确
for (let x of Array.from(arrayLike)) {
  console.log(x);
}

objetos

Para los objetos ordinarios, for...ofla estructura no se puede utilizar directamente, se quejan, debe ser desplegado con el fin de utilizar la interfaz iterador. Sin embargo, en este caso, el for...inciclo puede todavía ser utilizado para atravesar las llaves.

let es6 = {
  edition: 6,
  committee: "TC39",
  standard: "ECMA-262"
};

for (let e in es6) {
  console.log(e);
}
// edition
// committee
// standard

for (let e of es6) {
  console.log(e);
}
// TypeError: es6[Symbol.iterator] is not a function

Los códigos anteriores indican objetos ordinarios for...inciclo puede atravesar las llaves, for...ofel error ciclo.

Una solución es utilizar Object.keysel método para generar el objeto de una claves de matriz, y luego atravesar la matriz.

for (var key of Object.keys(someObject)) {
  console.log(key + ': ' + someObject[key]);
}

Otro método es utilizar la función de objeto generador será volver a empaquetar.

function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

for (let [key, value] of entries(obj)) {
  console.log(key, '->', value);
}
// a -> 1
// b -> 2
// c -> 3

Comparación con otros sintaxis traversal

Una matriz, por ejemplo, JavaScript ofrece una variedad de sintaxis recorrido. El texto más original está forcirculando.

for (var index = 0; index < myArray.length; index++) {
  console.log(myArray[index]);
}

La redacción es demasiado problema, y por lo tanto ofrece una gran variedad de built-in forEachmétodo.

myArray.forEach(function (value) {
  console.log(value);
});

El enunciado de la pregunta que no puede estar a mitad de camino fuera del forEachbucle, breakel comando o returncomandos no son eficaces.

for...inLas claves pueden atravesar la matriz de bucle.

for (var index in myArray) {
  console.log(myArray[index]);
}

for...inCirculación tiene varios inconvenientes.

  • Las claves de matriz digital, pero el for...inciclo es una cadena de caracteres como teclas "0", "1", "2" y así sucesivamente.
  • for...inNo sólo las teclas numéricas del ciclo de recorrido, se pueden añadir manualmente otras teclas de desplazamiento, e incluso clave en la cadena de prototipo.
  • En algunos casos, for...inel ciclo recorrerá las teclas en cualquier orden.

En resumen, for...inel ciclo está principalmente diseñada para atravesar el objeto, éste no se aplica a atravesar la matriz .

for...ofCiclo en comparación con los varios enfoques anteriores, hay algunas ventajas significativas.

for (let value of myArray) {
  console.log(value);
}
  • Cuenta con for...inla misma sintaxis sencilla, pero sin for...inesos inconvenientes.
  • A diferencia forEachdel método, que puede estar asociada con break, continuey returnusado en conjunción.
  • A través de toda la estructura de datos proporciona una interfaz de usuario unificada.

La siguiente es una declaración de la rotura, de los for...ofejemplos del ciclo.

for (var n of fibonacci) {
  if (n > 1000)
    break;
  console.log(n);
}

El anterior ejemplo de salida voluntad la secuencia de Fibonacci de 1.000 o menos entradas. Si el elemento actual es mayor que 1000, se utilizará la breakdeclaración de saltar fuera del for...ofbucle.

Supongo que te gusta

Origin www.cnblogs.com/dxy9527/p/12515947.html
Recomendado
Clasificación