Home >Web Front-end >Front-end Q&A >What is the difference between for and foreach in es6

What is the difference between for and foreach in es6

青灯夜游
青灯夜游Original
2022-10-21 17:32:541562browse

Difference: 1. forEach is an iterator, which is responsible for traversing (Array Set Map) iterable objects; while for is a loop mechanism, which can only traverse arrays. 2. Some interrupt behaviors are used in the for loop, which is good for optimizing array traversal and search. However, because forEach is an iterator and can only be traversed in order, it does not support interrupt behaviors. 3. The starting point of the forEach loop can only be 0, and human intervention is not possible; unlike the for loop, the starting point of the loop can be controlled manually.

What is the difference between for and foreach in es6

The operating environment of this tutorial: Windows 7 system, ECMAScript version 6, Dell G3 computer.

The essential difference between for loop and forEach

forLoop is a loop method that was introduced in js.

forEach is a method proposed by ES5 and mounted on the prototype of an iterable object, such as Array Set Map.

forEach is an iterator, responsible for traversing iterable objects.

So what are traversal, iteration, iterable object respectively.

  • Traversal: refers to the regular and one-time access behavior to each member of the data structure.

  • Iteration: Iteration is a special form of recursion and a method provided by iterators. By default, it is in a certain orderone by oneAccess data structure members. Iteration is also a traversal behavior.

  • Iterable object: The iterable type was introduced in ES6, Array Set Map String arguments NodeList all belong to iterable, their characteristic is that they all have [Symbol.iterator] method, the object containing it is considered an iterable iterable.

forEach is actually an iterator. The essential difference between it and the for loop is that forEach is responsible for traversing (Array Set Map) Iterable object, and for loop is a loop mechanism, which can only traverse the array .

What is an iterator? When it is called, an iterator object (Iterator Object) will be generated. It has a .next() method. Each This call returns an object {value:value,done:Boolean}, value returns the return value after yield, when yieldEnd, done becomes true, and the internal value is accessed through continuous calls and sequential iterations.

Iterator is a special object. Its symbol in the ES6 specification is the next() method of the returned object, and the iteration behavior is judged in done. Iterators implement traversal without exposing the internal representation. Looking at the code

let arr = [1, 2, 3, 4]  // 可迭代对象
let iterator = arr[Symbol.iterator]()  // 调用 Symbol.iterator 后生成了迭代器对象
console.log(iterator.next()); // {value: 1, done: false}  访问迭代器对象的next方法
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 4, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

we see. As long as it is an iterable object, calling the internal Symbol.iterator will provide an iterator, and access the internals based on the next method returned by the iterator, which is also for.. The implementation principle of .of.

let arr = [1, 2, 3, 4]
for (const item of arr) {
    console.log(item); // 1 2 3 4 
}

Call the next method to return the value value of the object and save it in item until value is undefined Break out of the loop and all iterable objects are available for for...of consumption. Let’s look at other iterable objects:

function num(params) {
    console.log(arguments); // Arguments(6) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    let iterator = arguments[Symbol.iterator]()
    console.log(iterator.next()); // {value: 1, done: false}
    console.log(iterator.next()); // {value: 2, done: false}
    console.log(iterator.next()); // {value: 3, done: false}
    console.log(iterator.next()); // {value: 4, done: false}
    console.log(iterator.next()); // {value: undefined, done: true}
}
num(1, 2, 3, 4)

let set = new Set('1234')
set.forEach(item => {
    console.log(item); // 1 2 3 4
})
let iterator = set[Symbol.iterator]()
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 4, done: false}
console.log(iterator.next()); // {value: undefined, done: true}

So the Symbol.iterator property in the iterable object can generate an iterator when it is called, and forEach is also generated An iterator that passes out the value of each element in the inner callback function

<span style="font-size: 20px;">for</span>loop and <span style="font-size: 20px;">forEach</span>

parameters forEach

.

  • forEach

    interrupt.

  • forEach

    Delete its own element, and the index cannot be reset.

  • #for

    Loops can control the starting point of the loop.

  • parameters of forEach

  • Do we really understand the complete parameter content of
forEach

? It probably looks like this: <pre class="brush:php;toolbar:false">arr.forEach((self,index,arr) =&gt;{},this)</pre>

######self: ### The elements currently traversed by the array, the array elements are obtained from left to right by default. ###############index: ### The index of the current element of the array, the first element index is 0, and so on. ################arr: ### The currently traversed array. ###############this: ### This points to the callback function. #########
let arr = [1, 2, 3, 4];
arr.forEach(function (self, index, arr) {
    console.log(`当前元素为${self}索引为${index},属于数组${arr}`);
}, person)
###We can use ###arr### to achieve array deduplication: ###
let arr1 = [1, 2, 1, 3, 1];
let arr2 = [];
arr1.forEach(function (self, index, arr) {
    arr.indexOf(self) === index ? arr2.push(self) : null;
});
console.log(arr2);   // [1,2,3]

forEach 的中断

在js中有break return continue 对函数进行中断或跳出循环的操作,我们在 for循环中会用到一些中断行为,对于优化数组遍历查找是很好的,但由于forEach属于迭代器,只能按序依次遍历完成,所以不支持上述的中断行为。

let arr = [1, 2, 3, 4],
    i = 0,
    length = arr.length;
for (; i < length; i++) {
    console.log(arr[i]); //1,2
    if (arr[i] === 2) {
        break;
    };
};

arr.forEach((self,index) => {
    console.log(self);
    if (self === 2) {
        break; //报错
    };
});

arr.forEach((self,index) => {
    console.log(self);
    if (self === 2) {
        continue; //报错
    };
});

如果我一定要在 forEach 中跳出循环呢?其实是有办法的,借助try/catch

try {
    var arr = [1, 2, 3, 4];
    arr.forEach(function (item, index) {
        //跳出条件
        if (item === 3) {
            throw new Error("LoopTerminates");
        }
        //do something
        console.log(item);
    });
} catch (e) {
    if (e.message !== "LoopTerminates") throw e;
};

若遇到 return 并不会报错,但是不会生效

let arr = [1, 2, 3, 4];

function find(array, num) {
    array.forEach((self, index) => {
        if (self === num) {
            return index;
        };
    });
};
let index = find(arr, 2);// undefined

forEach 删除自身元素,index不可被重置

forEach 中我们无法控制 index 的值,它只会无脑的自增直至大于数组的 length 跳出循环。所以也无法删除自身进行index重置,先看一个简单例子:

let arr = [1,2,3,4]
arr.forEach((item, index) => {
    console.log(item); // 1 2 3 4
    index++;
});

index不会随着函数体内部对它的增减而发生变化。在实际开发中,遍历数组同时删除某项的操作十分常见,在使用forEach删除时要注意。

for 循环可以控制循环起点

如上文提到的 forEach 的循环起点只能为0不能进行人为干预,而for循环不同:

let arr = [1, 2, 3, 4],
    i = 1,
    length = arr.length;

for (; i < length; i++) {
    console.log(arr[i]) // 2 3 4
};

那之前的数组遍历并删除滋生的操作就可以写成

let arr = [1, 2, 1],
    i = 0,
    length = arr.length;

for (; i < length; i++) {
    // 删除数组中所有的1
    if (arr[i] === 1) {
        arr.splice(i, 1);
        //重置i,否则i会跳一位
        i--;
    };
};
console.log(arr); // [2]
//等价于
var arr1 = arr.filter(index => index !== 1);
console.log(arr1) // [2]

<span style="font-size: 18px;">for</span>循环和<span style="font-size: 18px;">forEach</span>的性能区别

在性能对比方面我们加入一个 map 迭代器,它与 filter 一样都是生成新数组。

对比 for forEach map 的性能在浏览器环境中都是什么样的:

性能比较:for > forEach > map 在chrome 62 和 Node.js v9.1.0环境下:for 循环比 forEach 快1倍,forEachmap 快20%左右。

原因分析for:for循环没有额外的函数调用栈和上下文,所以它的实现最为简单。

forEach:对于forEach来说,它的函数签名中包含了参数和上下文,所以性能会低于 for 循环。

mapmap 最慢的原因是因为 map 会返回一个新的数组,数组的创建和赋值会导致分配内存空间,因此会带来较大的性能开销。

如果将map嵌套在一个循环中,便会带来更多不必要的内存消耗。

当大家使用迭代器遍历一个数组时,如果不需要返回一个新数组却使用 map 是违背设计初衷的。

【相关推荐:javascript视频教程编程视频

The above is the detailed content of What is the difference between for and foreach in es6. For more information, please follow other related articles on the PHP Chinese website!

Statement:
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