A deep understanding of iterator and for-of cycles in JavaScript basics

Source: Internet
Author: User
Tags iterable new set in python

How do I traverse an array of elements? 20 years ago, when JavaScript appeared, you might do this:

for (var index = 0; index < myarray.length; index++) {
 console.log (Myarray[index]);
}
 
for (var index = 0; index < myarray.length; index++) {
 console.log (Myarray[index]);
}

Since ES5 started, you can use the built-in ForEach method:

JavaScript
Myarray.foreach (function (value) {
 console.log (value);
});
 
Myarray.foreach (function (value) {
 console.log (value);
});

The code is more streamlined, but there is a small drawback: you cannot use the break statement to jump out of the loop, and you cannot use the return statement to get back from the closure function.

It would be much easier if you had for-this syntax to traverse an array.

So, how about using for-in?

For (var index in myarray) {//Do not do this in the actual code
 console.log (Myarray[index]);
}

 
For (var index in myarray) {//Do not do this in the actual code
 console.log (Myarray[index]);
}

This is not good because:

The index variable in the code above will be a string such as "0", "1", "3", and not a numeric type. If you use the index of the string to participate in some operations ("2" + 1 = "21"), the result of the operation may be inconsistent with the expected.
Not only will the elements of the array itself be traversed, but the additional (expando) elements added by the user will also be traversed, such as an array having such a property myarray.name, then a index= "name" will appear in a loop. Furthermore, even properties on the chain of an array prototype may be traversed.
The most incredible thing is that in some cases the code above will iterate over the elements of the array in any order.

In simple terms, the purpose of the for-in design is to traverse objects that contain key-value pairs, which are not so friendly to the array.
a powerful for-of cycle

Remember last time I mentioned, ES6 does not affect the normal operation of existing JS code, there are thousands of WEB applications are dependent on the characteristics of the for-in, and even rely on for-in for the characteristics of the array, so no one has ever proposed "improve" the existing for-in syntax to fix the problem. ES6 the only way to solve this problem is to introduce a new loop traversal syntax.

This is the new syntax:

for (var value of myarray) {
 console.log (value);
}
 
for (var value of myarray) {
 console.log (value);
}

By introducing the for-in syntax above, this syntax does not look very impressive. We'll detail the wonders of for-of in the back, and now you just need to know:

    • This is the simplest and most straightforward way to traverse an array.
    • Avoids all the holes in the for–in grammar.
    • Unlike ForEach (), it supports break, continue, and return statements.

For–in is used to traverse the properties of an object.

For-of is used to traverse data-just like an element in an array.

However, this is not all the for-of features, there are more exciting parts below.
other collections that support for-of

For-of is not only an array design, it can also be used for objects of a class array, such as a collection of DOM objects nodelist.

It can also be used to traverse a string, which looks at a string as a collection of Unicode characters:

It also applies to Map and Set objects.

You may never have heard of Map and Set objects, as they are new objects in ES6, and there will be separate articles to describe them in detail later. If you've used these two objects in other languages, that's a lot easier.

For example, you can use a set object to weigh the array elements:

JavaScript
//Make a set from an array of words
var uniquewords = new set (words);
 
Make a set from a array of words
var uniquewords = new set (words);

When you get a Set object, you'll probably go through the object, which is simple:

for (var word of uniquewords) {
 console.log (word);
}
 
for (var word of uniquewords) {
 console.log (word);
}

The Map object is made up of key-value pairs, and the traversal is slightly different, and you need two separate variables to receive the keys and values individually:

for (var [key, value] of Phonebookmap) {
 Console.log (key + "' s phone number is:" + value);
}
 
for (var [key, value] of Phonebookmap) {
 Console.log (key + "' s phone number is:" + value);
}

So far, you already know: JS has supported some collection objects, and will support more later. The for-of syntax is designed for these collection objects.

For-of cannot be used directly to traverse the properties of an object, and if you want to traverse the object's properties, you can use the For-in statement (for-in is used to do this), or use the following method:

Dump an object ' s own enumerable properties to the console for
(var key of Object.keys (Someobject)) {
 Console.lo G (Key + ":" + Someobject[key]);
}

 
Dump an object ' s own enumerable properties to the console for
(var key of Object.keys (Someobject)) {
 Console.lo G (Key + ":" + Someobject[key]);
}

Internal principle

"Good artist copy, great artist steals." "-Pablo Picasso

The new features that are added to the ES6 are not without chapters, most of which have been used in other languages, and the fact that these features are useful.

Take the for-of statement, there are similar looping statements in C + +, JAVA, C #, and Python, and are used to traverse the language and the various data structures in its standard libraries.

As with for and foreach statements in other languages, for-of requires that the object being traversed implement a specific method. All of the Array, Map, and Set objects have one thing in common: they all implement an iterator (iterator) method.

So, if you want, you can implement an iterator approach to any other object.

It's like you can implement a myobject.tostring () method for an object to tell the JS engine how to convert an object to a string, or you can implement a Myobject[symbol.iterator] () method for any object to tell JS How the engine goes through the object.

For example, if you are using jquery and are very fond of using its each () method, now you want to make all jquery objects support for-of statements, you can do this:

Since JQuery objects are array-like,
//give them the same iterator method Arrays have
. Iterator] =
 Array.prototype[symbol.iterator];

 
Since JQuery objects are array-like,
//give them the same iterator method Arrays have
. Iterator] =
 Array.prototype[symbol.iterator];

You may be wondering why [symbol.iterator] syntax looks so strange? What do you mean by that remark? The key to the problem is the method name, the ES Standard committee can completely name the method iterator (), but there may already be a method named "iterator" in the existing object, which will cause code confusion and violate the maximum compatibility principle. So, the standard Committee introduced Symbol, not just a string, as the method name.

Symbol is also a new feature of ES6, followed by a separate article to introduce. Now all you need to know is that the standard board introduced new Symbol, such as symbol.iterator, to not conflict with previous code. The only disadvantage is that the syntax is a bit strange, but for this powerful new feature and perfect back-compatibility, this is trivial.

An object with [Symbol.iterator] () method is considered to be ergodic (iterable). In a later article, we'll see that the concept of "ergodic objects" runs throughout the language, not only in for-of statements, but also in the constructor and destructor (destructuring) functions of Map and Set, and in new extension operators.
Iterator Object

Usually we don't completely start from scratch to implement an iterator (iterator) object, and the next article will tell you why. But for the sake of completeness, let's look at what an iterator object is exactly like. (If you skip this section, you'll miss out on some technical details.) )

Take the for-of statement, which first invokes the [Symbol.iterator] () method that is traversing the collection object, which returns an iterator object that can be any object that owns the. Next method; and then, in every loop of for-of, Will call the. Next method on the iterator object. The following is one of the simplest iterator objects:

var zeroesforeveriterator = {
 [Symbol.iterator]: function () {return this
 ;
 },
 next:function () {
 return {done:false, value:0};
 }
;
 
var zeroesforeveriterator = {
 [Symbol.iterator]: function () {return this
 ;
 },
 next:function () { C14/>return {done:false, value:0};
 }
;

In the code above, the same result is returned each time the. Next () method is invoked, which tells the for-of statement that the loop traversal is not over, on the other hand, tells the for-of statement that the value of this loop is 0. This means that for (value of Zeroesforeveriterator) {} is a dead loop. Of course, a typical iterator is not so simple.

The ES6 iterator uses the two properties of. Done and. Value to identify each traversal result, which is the design principle of the iterator, which differs from the iterator in other languages. In Java, an iterator object uses the. Hasnext () and. Next () two methods, respectively. In Python, the iterator object has only one. Next () method, which throws a stopiteration exception when there are no elements to iterate over. But fundamentally, all three of these designs return the same information.

The iterator object can also optionally implement. return () and. throw (exc) methods. If the loop exits prematurely because of an exception or using the break and return operators, then the iterator's. return () method is invoked to free the resource occupied by the iterator object by implementing the. return () method, but most iterators do not need to implement this method. Throw (exc) is a special case: This method will never be invoked during traversal, and I will explain this in more detail in the next article.

Now that we know all the details of for-of, we can simply rewrite the statement.

The first is the for-of circulation body:

For (Var of iterable) {
 statements
} for
 
(var of iterable) {
 statements
}

This is just a semantic implementation, using some of the underlying methods and several temporary variables:

var $iterator = Iterable[symbol.iterator] ();
var $result = $iterator. Next ();
while (! $result. Done) {
 VAR = $result. Value;
 Statements
 $result = $iterator. Next ();

 
var $iterator = Iterable[symbol.iterator] ();
var $result = $iterator. Next ();
while (! $result. Done) {
 VAR = $result. Value;
 Statements
 $result = $iterator. Next ();


The above code does not involve how to invoke the. return () method, we can add the corresponding processing, but I think this will affect our understanding of the internal principles. The for-of statement is very simple to use, but there is a lot of detail inside it.
Compatibility

Currently, all versions of Firefox release have support for for-of statements. Chrome disables the statement by default, and you can enter chrome://flags into the Settings page in the Address bar, and then check the "Experimental JavaScript" option. Microsoft's Spartan Browser also supports the statement, but IE does not support it. If you want to use this statement in WEB development and need to be compatible with IE and Safari browsers, you can use Babel or Google's traceur compiler to convert ES6 code to web-friendly ES5 code.

For the server side, we don't need any compilers-you can use the statement directly in Io.js, or use the--harmony startup option when Nodejs starts.

{Done:true}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.