ECMAScript 7: "for of" loops and destructuring

1381
0
07-17-2019 01:00 AM
StephenQuan1
Esri Contributor
0 0 1,381

1. Introduction

This blog is about the Javascript "for of" loop and the Javascript destructuring assignment.

These are part of ECMAScript 6 features that were included in the ECMAScript 7 update of AppStudio 3.3 and Qt 5.12.1.

We explore how these features may help with your AppStudio apps.



2. The "for of" loop

Traditionally, to loop through an array we need to use an index variable (e.g. i):

var census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for (var i = 0; i < census.length; i++) {
    var item = census[i]
    console.log( item.country, item.population )
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

In ECMAScript 6, we can use "for of" loop to make this easier:

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for ( let item of census ) {
    console.log( item.country, item.population )
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The "for of" loop is new in ECMAScript 6 and created specifically for looping through arrays and, in general, Javascript iterators.


3. Unpacking object values

Since we know each item have country and population fields, we can use the new ECMAScript destructuring assignment operator to extract it:

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for ( let item of census ) {
    let { country, population } = item
    console.log( country, population )
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

We can even mix destructuring assignment with "for of":

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for ( let { country, population } of census ) {
    console.log( country, population )
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You can get creative by combining this with arrow functions:

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
let orderByPopulationDesc = (a, b) => -(a.population - b.population)
for ( let { country, population } of census.sort( orderByPopulationDesc ) ) {
    console.log( country, population )
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍



4. Unpacking arrays values

Similarly, you can unpack arrays using the following destructuring assignment syntax:

let [ year, month, day ] = [ "2019", "11", "07" ]
console.log(year) // 2019
console.log(month) // 11
console.log(day) // 07‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

5. Unpacking regular expression capture groups

When you use "str.match" with regular expression you get an array of strings. You get additional strings in the array for each capture group. You need to process the array to extract each capture group, e.g.

let str = "2019-11-07"
let m = str.match( /(\d{4})-(\d{2})-(\d{2})/ )
console.log( m.length ) // 4
console.log( m[0] ) // 2019-11-07
console.log( m[1] ) // 2019
console.log( m[2] ) // 11
console.log( m[3] ) // 07‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The Javascript destructuring assignment here helps eliminate the need for having an intermediate array variable. The code becomes much shorter and clearer:

let str = "2019-11-07"
let [ , year, month, day ] = str.match(/(\d{4})-(\d{2})-(\d{2})/)
console.log( year ) // 2019
console.log( month ) // 11
console.log( day ) // 07‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

6. Using destructuring assignment with SQL

In the following example, we see that the destructuring assignment is useful in unpacking results from SQL queries:

db.open()
db.query( "CREATE TABLE IF NOT EXISTS countries (country TEXT, population NUMBER)" )
db.query( "INSERT INTO countries VALUES ( 'France', 66.99 )" )
db.query( "INSERT INTO countries VALUES ( 'Australia', 24.6 )" )
db.query( "INSERT INTO countries VALUES ( 'USA', 327.2 )" )
let q = db.query( "SELECT * FROM countries" )
for ( let ok = q.first() ; ok ; ok = q.next() ) {
    let { country, population } = q.values
    console.log( country, population )
}
q.finish()
db.close()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

We can use "for of" syntax here if we make use of Javascript iterator and Javascript generator syntax:

function* queryIterator(q) {
    for ( let ok = q.first() ; ok ; ok = q.next() )
        yield q.values
}

db.open()
db.query( "CREATE TABLE IF NOT EXISTS countries (country TEXT, population NUMBER)" )
db.query( "INSERT INTO countries VALUES ( 'France', 66.99 )" )
db.query( "INSERT INTO countries VALUES ( 'Australia', 24.6 )" )
db.query( "INSERT INTO countries VALUES ( 'USA', 327.2 )" )
let q = db.query( "SELECT * FROM countries" )
for ( let { country, population } of queryIterator( q ) ) {
    console.log( country, population )
}
q.finish()
db.close()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

We will talk more about Javascript iterators and Javascript generators in a future blog.

7. Conclusion

This blog introduces Javascript "for of" loop and Javascript destructuring assignments.

These are some of the new Javascript ECMAScript 7 syntax improvements in AppStudio 3.3 and Qt 5.12.1 that can help you improve your code readability, clarity by helping you write shorter, easier to maintain code.

These syntax improvements complement other Javascript improvements, such as Javascript iterators, Javascript generators and Javascript promises.

We will introduce Javascript iterators and Javascript generators in a future blog.

We will revisit Javascript promises and how they fit with all these Javascript syntax improvements.