<> interviewer : Yes for loop Why forEach?
js So many cycles in ,for for…in for…of
forEach, Some cycles feel similar. Let's talk about them today for Cycle and forEach Differences in . Let's start the discussion from several dimensions :
1.for Cycle and forEach Essential difference between .
2.for Cycle and forEach Grammatical differences of .
3.for Cycle and forEach Performance differences .
Essential difference
for Cycle is js Circulation method existed when it was proposed .forEach yes ES5 Proposed , Methods for mounting on iteratible object prototypes , for example Array Set
Map.forEach Is an iterator , Responsible for traversing iteratible objects . So traversal , iteration , What are the iteratable objects .
ergodic : It refers to the regular and one-time access to each member of a data structure . iteration : Iteration is a special form of recursion , Is a method provided by iterators , By default, data structure members are accessed one by one in a certain order . Iteration is also an ergodic behavior . Iteratible object :ES6 Introduced in
iterable type ,Array Set Map String arguments NodeList All belong to iterable, They all have
[Symbol.iterator] method , The object containing it is considered iterative iterable.
After knowing this, I know forEach It's actually an iterator , He and for The essential difference between loops is forEach Is responsible for traversal (Array Set
Map) Of iteratible objects , and for Loop is a loop mechanism , It just iterates through the array . Let's talk about what an iterator is , Remember what I mentioned earlier Generator
generator , An iterator object is generated when it is called (Iterator Object), It has a
.next() method , One object per call {value:value,done:Boolean},value Returned yes yield Return value after , When yield
end ,done Become true, Accessing internal values through successive calls and successive iterations . Iterators are special objects .ES6 In the specification, its flag returns the object next()
method , Iterative behavior judgment in done in . Without exposing the internal representation , Iterators implement traversal . Look at the code
let arr = [1, 2, 3, 4] // Iteratible object let iterator = arr[Symbol.iterator]() // call
Symbol.iterator Iterator object generated after console.log(iterator.next()); // {value: 1, done:
false} To access the iterator object next method 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 saw it . As long as it is an iteratable object , Call internal Symbol.iterator Will provide an iterator , And based on the next Method to access the internal , This too
for…of Implementation principle of .
let arr = [1, 2, 3, 4] for (const item of arr) { console.log(item); // 1 2 3 4
}
Call next Method returns the value Value and save in item in , until value by undefined
Jump out of loop , All iteratible objects are available for for…of consumption . Let's look at other iteratible 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 we can also intuitively see the Symbol.iterator An iterator can be generated when a property is called , and forEach
Also generate an iterator , Pass the value of each element in the internal callback function .( Interested students can search forEach Source code , Array Set Map All instances are attached
forEach , But most of the answers on the Internet are through length Judge length , utilize for Loop mechanism implemented . But in Set Map
Error will be reported when used on , So I think it's an iterator of calls , Continuous call next, Pass parameter to callback function . Because I can't find the answer on the Internet, I won't make a rash assertion , People with answers can leave me a message in the comment area )
for Cycle and forEach Grammatical differences of
Understand the essential difference , During application , What are the grammatical differences between them ?
1.forEach Parameters for .
2.forEach Interrupt for .
3.forEach Delete own element ,index Cannot be reset .
4.for Loop can control the start point of the loop .
forEach Parameters for
We really know forEach Is the complete parameter transfer content of ? It's like this :
arr.forEach((self,index,arr) =>{},this)
self: Elements currently traversed by the array , Get array elements from left to right by default .index: Index of the current element of the array , The first element index is 0, By analogy .arr: Array currently traversed .this: In callback function this point .
let arr = [1, 2, 3, 4]; let person = { name: ' Technical straight star ' }; arr.forEach(function
(self, index, arr) { console.log(` Current element is ${self} Index is ${index}, Belong to array ${arr}`);
console.log(this.name+=' How handsome '); }, person)
We can use arr Implement array de duplication :
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 Interrupt for
stay js There are break return continue Interrupt or jump out of a loop on a function , We are
for Some interrupt behaviors are used in the loop , Good for optimizing array traversal lookups , But because forEach Belongs to iterator , Can only be traversed sequentially , Therefore, the above interrupt behavior is not supported .
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; // report errors
}; }); arr.forEach((self,index) => { console.log(self); if (self === 2) {
continue; // report errors }; });
If I had to forEach Out of the loop ? There is a way , With the help of try/catch:
try { var arr = [1, 2, 3, 4]; arr.forEach(function (item, index) { // Jump out condition if
(item === 3) { throw new Error("LoopTerminates"); } //do something
console.log(item); }); } catch (e) { if (e.message !== "LoopTerminates") throw
e; };
If encountered return No error will be reported , But it will not take effect
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 Delete own element ,index Cannot be reset
stay forEach We can't control index Value of , It will only increase mindlessly until it is greater than the length
Jump out of loop . Therefore, you cannot delete your own index Reset , Let's start with a simple example :
let arr = [1,2,3,4] arr.forEach((item, index) => { console.log(item); // 1 2 3
4 index++; });
index It will not change as the function body increases or decreases . In actual development , It is very common to traverse an array and delete an item at the same time , in use forEach Note when deleting .
for Loop can control the start point of the loop
As mentioned above forEach The start point of the cycle can only be 0 No human intervention , and for Different cycles :
let arr = [1, 2, 3, 4], i = 1, length = arr.length; for (; i < length; i++) {
console.log(arr[i]) // 2 3 4 };
The previous array traversal and deletion operations can be written as
let arr = [1, 2, 1], i = 0, length = arr.length; for (; i < length; i++) { //
Delete all in the array 1 if (arr[i] === 1) { arr.splice(i, 1); // Reset i, otherwise i Can jump one i--; }; };
console.log(arr); // [2] // Equivalent to var arr1 = arr.filter(index => index !== 1);
console.log(arr1) // [2]
for Cycle and forEach Performance differences
In terms of performance comparison, we add a map iterator , It and filter The same is to generate a new array . We compare for forEach map
What is the performance of in a browser environment : performance comparison :for > forEach > map stay chrome 62 and Node.js v9.1.0 Environment :for
Cycle ratio forEach fast 1 times ,forEach than map fast 20% about .
Cause analysis for:for Loop has no additional function call stack and context , So its implementation is the simplest .forEach: about forEach Say , Its function signature contains parameters and context , So the performance will be lower than
for loop .map:map The slowest reason is because map
Will return a new array , The creation and assignment of arrays will result in the allocation of memory space , Therefore, it will bring large performance overhead . If map Nested in a loop , Will cause more unnecessary memory consumption . When you use iterators to traverse an array , If you do not need to return a new array but use
map It is against the original intention of the design . When I was working on the front-end cooperative development, I saw many people just use it to traverse arrays map of :
let data = []; let data2 = [1,2,3]; data2.map(item=>data.push(item));
Write at the end : This is a question I met during the interview , At that time, only grammatical differences were known . Not from iteratible object , iterator , Generator and performance aspects , Further distinguish the similarities and differences between the two from multiple angles , I also hope I can elaborate on a simple problem from multiple perspectives , So that everyone is getting to know .
Technology
Daily Recommendation