2017-08-15 10 views
0

L'ordre d'itération à travers un tableau en utilisant l'une des méthodes natives (map, forEach, reduce, filter, etc.) est-il déterministe et garanti par la norme?L'ordre d'itération des méthodes du tableau javascript (map, forEach, reduce, etc.) est-il déterministe?

EG, foo, bar, baz et qux sont-ils garantis [0, 2, 6, 12]?

const a = [1, 2, 3, 4]; 
const foo = a.map((item, index) => item * index); 
const bar = []; a.forEach((item, index) => bar[index] = item * index); 
const baz = []; a.reduce((total, item, index) => baz[index] = item * index, 0); 
const qux = []; a.filter((item, index) => qux[index] = item * index); 
// etc 

(Ce sont (très) des exemples artificiels)

+2

Oui, les propriétés numériques sont traversées dans l'ordre croissant. Il est explicitement décrit dans la spécification de la langue. – Pointy

+0

btw, vous devez utiliser une valeur de départ pour réduire, comme 'a.reduce ((total, élément, index) => baz [index] = élément * index, null);' –

Répondre

1

La fonction de rappel est appelée pour chaque élément présent dans le tableau, dans l'ordre croissant. C'est pas appelé pour les éléments manquants. (Éléments manquants Oui, JavaScript gérer des tableaux rares?)

var test = []; 
test[30] = 'Test'; // sparse array, only one element defined. 

test.forEach(
    function(value){ 
    console.log(value); // will only be called one time. 
    } 
); 

de la norme: ECMA-262

22.1.3.10 Array.prototype.forEach (callbackfn [, thisArg])

NOTE 1

callbackfn devrait être une fonction qui accepte trois arguments. pourChaque appelle callbackfn une fois pour chaque élément présent dans le tableau, dans l'ordre croissant. callbackfn est appelé uniquement pour les éléments de le tableau qui existe réellement; il n'est pas appelé pour les éléments manquants du tableau

Si un paramètre thisArg est fourni, il sera utilisé comme cette valeur pour chaque invocation de callbackfn. Si ce n'est pas le cas, non défini est utilisé à la place.

callbackfn est appelée avec trois arguments: la valeur de l'élément , l'indice de l'élément, et l'objet étant traversée.

forEach ne mute pas directement l'objet sur lequel il est appelé, mais l'objet peut être muté par les appels à callbackfn.

Lorsque la méthode forEach est appelée avec un ou deux arguments, les mesures suivantes sont prises:

  1. Soit O? ToObject (cette valeur).
  2. Soit len ​​être? ToLength (? Get (O, "longueur")).
  3. Si IsCallable (callbackfn) est false, lancez un TypeError exception.
  4. Si thisArg a été fourni, soit T thisArg; sinon laissez T être non défini.
  5. Soit k 0.
  6. Répéter, tandis que k < len a. Laissez Pk être! ToString (k). b. Laisser kPresent être? HasProperty (O, Pk). c. Si kPresent est vrai, alors i. Laisser kValue être ? Obtenez (O, Pk). ii. Effectuer? Appel (callbackfn, T, «kValeur, k, O»). ré. Augmenter k de 1.
  7. Retour undefined.
1

En général, ils se comportent exactement comme cette boucle:

for(var i = 0; i < this.length; i++) 

Theres une exception près, reduceRight itère comme ceci:

for(var i = this.length - 1; i+1 ; i--) 

Contrairement à l'exemple supérieur es, ils sautent par-dessus des propriétés non définies.

+1

Ceci est vrai, mais ça vaut aussi notant que les emplacements non définis dans le tableau ou l'objet de type tableau sont ignorés. (Habituellement.) – Pointy

+0

Non, ils ne se comportent pas comme une boucle forcée qui traverse chaque index. Ils ne traversent que des index définis. C'est plus comme 'input_array = [0,1,2]; input_array [30] = 30; Pour (let keys = Object.keys (table_entrée), idx = 0, len = keys.length; idx some

+0

@some pas cet exemple est complètement faux. Et je vais ajouter une note ... –