Can es6's for of traverse objects?
es6's "for of" cannot traverse objects. Reason: The Iterator interface was introduced in ES6. Only data types that provide the Iterator interface can be traversed using "for-of"; while ordinary objects do not provide an Iterator interface by default, so "for-of" cannot be used for traversal.
The operating environment of this tutorial: Windows 7 system, ECMAScript version 6, Dell G3 computer.
With the continuous development of front-end, many methods of light loop have appeared, such as for, forEach, do..while, for...in, etc. However, these loops also have their own application scenarios. and advantages and disadvantages.
ES6 provides us with a new loop method for...of, which can loop strings, arrays and other array-like objects. As the most common Object object, it stands to reason that it can be looped?
Let’s take a look at the code example below:
{ // 迭代数组 const iterable = ['a', 'b']; for (const value of iterable) { console.log(value); } // output: a b } { // 普通对象 const obj = { a: 'A', b: 'B' } for(const item of obj){ console.log(item) } // Uncaught TypeError: obj is not iterable }
oh no, an error was reported: Uncaught TypeError: obj is not iterable
. Tip: obj is not iterable. Obviously, it is not possible to directly use for...of
to traverse the Object object.
So why can't for...of, which can traverse most data structures, traverse Object objects?
Reason:
Iterator was introduced in ES6. Only data types that provide the Iterator interface can be used to loop through for-of, while Array, Data types such as Set, Map, and certain arrays such as arguments all provide the Iterator interface by default, so they can be traversed using for-of.
For ordinary objects, the for...of structure cannot be used directly, and an error will be reported, prompting obj is not iterable
, which means that ordinary objects do not have an Iterator interface by default. The Iterator interface must be deployed before it can be used.
How to deal with it? Let for-of traverse the object
So the reason is clear, how to solve it? Can it provide an Iterator interface for objects and other data types?
The answer is yes, ES6 also provides the Symbol.iterator attribute. As long as a data structure has this attribute, it will be regarded as having an Iterator interface. , then there is how to implement this interface. The following is the simplest implementation:
newObj[Symbol.iterator] = function(){ let index = 0 , self = this , keys = Object.keys( self ) ; return { next(){ if( index < keys.length ){ return { value: self[keys[index++]] , done: false }; } else{ return { value: undefined , done: true } } } }; };
If you look carefully, you will find that the Symbol.iterator interface is actually a Generator function, then you can simplify the code:
newObj[Symbol.iterator] = function* (){ let keys = Object.keys( this ) ; for(let i = 0, l = keys.length; i < l; i++){ yield this[keys[i]]; } } for(let v of newObj){ console.log( v ); } // 输出结果 // 5 // 6
It is worth noting that Object.keys happens to solve the inheritance problem encountered by for-in before
This meets our expectations and uses for-of to traverse the object, but something seems wrong, we traverse Objects are generally expected to output key and value at the same time. Adjusting the code like this
newObj[Symbol.iterator] = function* (){ let keys = Object.keys( this ) ; for(let i = 0, l = keys.length; i < l; i++){ yield { key: keys[i] , value: this[keys[i]] }; } } for(let v of newObj){ console.log( v ); } // 输出结果 // {key: "e", value: 5} // {key: "f", value: 6}
returns an object, which seems very uncomfortable. Can we try some destructuring assignment? . .
for(let {key, value} of newObj){ console.log(key, value ); } // 输出结果 // e 5 // f 6
This seems perfect. . .
Extended knowledge: The difference between for-of and other loops
Loop object | Whether the loop can be interrupted | Is there a return value | |
---|---|---|---|
| forThe length of the loop body can be |
No return value | |
Only can be looped | Arrays, maps, sets, etc. cannot be looped, strings, ordinary objects Not possible |
No return value | |
If certain conditions are met, it can be looped all the time, at least once |
Yes | No return value | |
If certain conditions are met, the loop can be continued |
Yes | No return value | |
Form a new array member. Only arrays can be looped, strings and ordinary objects cannot be looped, set , map |
Uninterruptible | Returns a new array, does not affect the original array | |
Filtering Array members, only arrays can be looped, strings and ordinary objects cannot be looped, set, map |
cannot be interrupted | returns a new array and does not affect the original array | |
Can be cycled | Array, object, cannot be cycledmap,set . Can traverse numeric key names, and can also traverse other manually added keys, even keys on the prototype chain Can |
No return value | |
Loopable iterable objects, non-loopable ordinary objects (unified data structure traversal) |
Can | No return value |
The above is the detailed content of Can es6's for of traverse objects?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

async is es7. async and await are new additions to ES7 and are solutions for asynchronous operations; async/await can be said to be syntactic sugar for co modules and generator functions, solving js asynchronous code with clearer semantics. As the name suggests, async means "asynchronous". Async is used to declare that a function is asynchronous; there is a strict rule between async and await. Both cannot be separated from each other, and await can only be written in async functions.

In ES6, you can use the reverse() method of the array object to achieve array reversal. This method is used to reverse the order of the elements in the array, putting the last element first and the first element last. The syntax "array.reverse()". The reverse() method will modify the original array. If you do not want to modify it, you need to use it with the expansion operator "...", and the syntax is "[...array].reverse()".

For browser compatibility. As a new specification for JS, ES6 adds a lot of new syntax and API. However, modern browsers do not have high support for the new features of ES6, so ES6 code needs to be converted to ES5 code. In the WeChat web developer tools, babel is used by default to convert the developer's ES6 syntax code into ES5 code that is well supported by all three terminals, helping developers solve development problems caused by different environments; only in the project Just configure and check the "ES6 to ES5" option.

Steps: 1. Convert the two arrays to set types respectively, with the syntax "newA=new Set(a);newB=new Set(b);"; 2. Use has() and filter() to find the difference set, with the syntax " new Set([...newA].filter(x =>!newB.has(x)))", the difference set elements will be included in a set collection and returned; 3. Use Array.from to convert the set into an array Type, syntax "Array.from(collection)".

In es5, you can use the for statement and indexOf() function to achieve array deduplication. The syntax "for(i=0;i<array length;i++){a=newArr.indexOf(arr[i]);if(a== -1){...}}". In es6, you can use the spread operator, Array.from() and Set to remove duplication; you need to first convert the array into a Set object to remove duplication, and then use the spread operator or the Array.from() function to convert the Set object back to an array. Just group.

In es6, the temporary dead zone is a syntax error, which refers to the let and const commands that make the block form a closed scope. Within a code block, before a variable is declared using the let/const command, the variable is unavailable and belongs to the variable's "dead zone" before the variable is declared; this is syntactically called a "temporary dead zone". ES6 stipulates that variable promotion does not occur in temporary dead zones and let and const statements, mainly to reduce runtime errors and prevent the variable from being used before it is declared, resulting in unexpected behavior.

No, require is the modular syntax of the CommonJS specification; and the modular syntax of the es6 specification is import. require is loaded at runtime, and import is loaded at compile time; require can be written anywhere in the code, import can only be written at the top of the file and cannot be used in conditional statements or function scopes; module attributes are introduced only when require is run. Therefore, the performance is relatively low. The properties of the module introduced during import compilation have slightly higher performance.

In ES6, you can use the length attribute of the array object to determine how many items there are in the array, that is, to get the number of elements in the array; this attribute can return the number of elements in the array, just use the "array.length" statement. Returns a value representing the number of elements of the array object, that is, the length value.
