Home > Web Front-end > JS Tutorial > The difference between the four array traversal methods in JS ( for , forEach() , for/in, for/of)

The difference between the four array traversal methods in JS ( for , forEach() , for/in, for/of)

青灯夜游
Release: 2020-10-28 17:46:22
forward
2523 people have browsed it

The difference between the four array traversal methods in JS ( for , forEach() , for/in, for/of)

We have multiple ways to traverse JavaScript arrays or objects, and the differences between them are very confusing. Airbnb Coding StyleFor/in and for/of are prohibited, do you know why? This article will introduce in detail the differences between the following four loop syntaxes:

    for (let i = 0; i < arr.length; i)
  • arr.forEach((v, i) => { /* ... */ })
  • for (let i in arr )
  • for (const v of arr)
  • Syntax

Use

for

and for/in, we can access the subscript of the array instead of the actual array element value: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">for (let i = 0; i &lt; arr.length; ++i) { console.log(arr[i]); } for (let i in arr) { console.log(arr[i]); }</pre><div class="contentsignin">Copy after login</div></div>Using

for/of

, we can directly access the element value of the array : <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">for (const v of arr) { console.log(v); }</pre><div class="contentsignin">Copy after login</div></div>Using

forEach()

, you can access the subscript and element value of the array at the same time: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">arr.forEach((v, i) =&gt; console.log(v));</pre><div class="contentsignin">Copy after login</div></div>Non-numeric attributes

JavaScript array It is Object, which means that we can add string attributes to the array:

const arr = ["a", "b", "c"];

typeof arr; // &#39;object&#39;

arr.test = "bad"; // 添加非数字属性

arr.test; // &#39;abc&#39;
arr[1] === arr["1"]; // true, JavaScript数组只是特殊的Object
Copy after login

4 loop syntaxes, only

for/in

will not ignore non-numeric attributes: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">const arr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]; arr.test = &quot;bad&quot;; for (let i in arr) { console.log(arr[i]); // 打印&quot;a, b, c, bad&quot; }</pre><div class="contentsignin">Copy after login</div></div> Because of this,

it is not good to

use for/in to traverse an array. The other three loop syntaxes will ignore non-numeric attributes:

const arr = ["a", "b", "c"];
arr.test = "abc";

// 打印 "a, b, c"
for (let i = 0; i < arr.length; ++i) {
    console.log(arr[i]);
}

// 打印 "a, b, c"
arr.forEach((el, i) => console.log(i, el));

// 打印 "a, b, c"
for (const el of arr) {
    console.log(el);
}
Copy after login

Points:

Avoid using for/in to traverse the array unless you Really want to iterate over non-numeric properties. You can use ESLint's guard-for-in rule to disable the use of for/in. Empty elements of arrays

JavaScript arrays can have

empty elements

. The following code syntax is correct, and the array length is 3:

What makes people even more confused is that the loop statement handles

['a',, 'c']

and ['a', undefined, 'c'] is not the same. For

['a',, 'c']

, for/in and forEach will skip empty elements, while for and for/of will not be skipped. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">// 打印&quot;a, undefined, c&quot; for (let i = 0; i &lt; arr.length; ++i) { console.log(arr[i]); } // 打印&quot;a, c&quot; arr.forEach(v =&gt; console.log(v)); // 打印&quot;a, c&quot; for (let i in arr) { console.log(arr[i]); } // 打印&quot;a, undefined, c&quot; for (const v of arr) { console.log(v); }</pre><div class="contentsignin">Copy after login</div></div>For

['a', undefined, 'c']

, the four loop syntaxes are the same, and "a, undefined, c" ​​is printed. There is another way to add empty elements:

// 等价于`[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;,, &#39;e&#39;]`
const arr = ["a", "b", "c"];
arr[5] = "e";
Copy after login

One more thing, JSON does not support empty elements either:

JSON.parse(&#39;{"arr":["a","b","c"]}&#39;);
// { arr: [ &#39;a&#39;, &#39;b&#39;, &#39;c&#39; ] }

JSON.parse(&#39;{"arr":["a",null,"c"]}&#39;);
// { arr: [ &#39;a&#39;, null, &#39;c&#39; ] }

JSON.parse(&#39;{"arr":["a",,"c"]}&#39;);
// SyntaxError: Unexpected token , in JSON at position 12
Copy after login

Points:

for/in and forEach will skip empty elements. Empty elements in the array are called "holes". If you want to avoid this problem, consider disabling the forEach:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">parserOptions: ecmaVersion: 2018 rules: no-restricted-syntax: - error - selector: CallExpression[callee.property.name=&quot;forEach&quot;] message: Do not use `forEach()`, use `for/of` instead</pre><div class="contentsignin">Copy after login</div></div> function of this

for

, for/in and for/of will retain this of the outer scope. For

forEach

, unless an arrow function is used, the this of its callback function will change. Use Node v11.8.0 to test the following code, the results are as follows:

"use strict";

const arr = ["a"];

arr.forEach(function() {
    console.log(this); // 打印undefined
});

arr.forEach(() => {
    console.log(this); // 打印{}
});
Copy after login

Points:

Use ESLint's no-arrow-callbackThe rules require that all callback functions must use arrow functions. Async/Await and Generators

One more thing,

forEach()

cannot "cooperate" well with Async/Await and Generators. Cannot use await in the

forEach

callback function: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">async function run() { const arr = [&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;]; arr.forEach(el =&gt; { // SyntaxError await new Promise(resolve =&gt; setTimeout(resolve, 1000)); console.log(el); }); }</pre><div class="contentsignin">Copy after login</div></div>Cannot use yield in the

forEach

callback function: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">function run() { const arr = [&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;]; arr.forEach(el =&gt; { // SyntaxError yield new Promise(resolve =&gt; setTimeout(resolve, 1000)); console.log(el); }); }</pre><div class="contentsignin">Copy after login</div></div> For

for/of

, there is no such problem: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">async function asyncFn() { const arr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]; for (const el of arr) { await new Promise(resolve =&gt; setTimeout(resolve, 1000)); console.log(el); } } function* generatorFn() { const arr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]; for (const el of arr) { yield new Promise(resolve =&gt; setTimeout(resolve, 1000)); console.log(el); } }</pre><div class="contentsignin">Copy after login</div></div> Of course, if you define the callback function of

forEach()

as an async function, no error will be reported However, if you want forEach to be executed in order, it will be a headache. The following code will print 0-9 from large to small:

async function print(n) {
    // 打印0之前等待1秒,打印1之前等待0.9秒
    await new Promise(resolve => setTimeout(() => resolve(), 1000 - n * 100));
    console.log(n);
}

async function test() {
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(print);
}

test();
Copy after login

Points:

Try not to use aysnc/await in forEach and generators. Conclusion

Simply put,

for/of

is the most reliable way to traverse an array. It is more concise than the for loop and has no for/in and forEach()So many strange special cases. The disadvantage of for/of is that it is inconvenient for us to get the index value, and we cannot call forEach(). forEach() in a chain like this. <p>使用<code>for/of获取数组索引,可以这样写:

for (const [i, v] of arr.entries()) {
    console.log(i, v);
}
Copy after login

参考

本文采用意译,版权归原作者所有

原文:http://thecodebarbarian.com/for-vs-for-each-vs-for-in-vs-for-of-in-javascript.html

相关免费学习推荐:js视频教程

更多编程相关知识,请访问:编程入门!!

The above is the detailed content of The difference between the four array traversal methods in JS ( for , forEach() , for/in, for/of). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:fundebug.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template