Web programming with ECMAScript 6
Importing Modules
Listing 4 shows how to use a module. The import
keyword handles integration in line 1. The following list (quoted in curly brackets and comma-separated) binds the pub
variable from the module to the a
variable and the pubObj
class to Obj
. The module is referenced using its file name without the .js
ending.
Listing 4
import-statement.html
The new
constructor in line 2 of Listing 4 passes a value of 4
, and the constructor in the next line a value of 5
, to the constructor function in Listing 3. The script parses the inc
attribute from both instantiated objects. The attribute results from the sum of the value passed to the constructor function and the value of the private variable priv
from Listing 3. The code first writes 5 and then 7 to the browser console, because priv
is incremented by 1 before the addition.
ECMAScript 6 provides the programmer with four new objects for storing data in the form of Map
, WeakMap
, Set
, and WeakSet
. Map
and WeakMap
are similar to JavaScript objects because they also store key-value pairs. Unlike traditional objects, map objects are iterable, however. They also accept any data type as an index. The difference between Map
and WeakMap
is in memory management: The garbage collector only deletes references that have exceeded their lifetime in WeakMap
objects.
In contrast, Set
and WeakSet
are similar to mathematical sets. They only store a value or a reference once. A re-add has no consequences. The garbage collector treats WeakSet
objects like WeakMap
objects. Set
and WeakSet
objects are also iterable.
For ease of parsing, ECMAScript 6 provides the newly created for
-of
loop. Because Traceur unfortunately does not support the four storage objects discussed above, the for
-of
loop in Listing 5 iterates against a field, because fields are also iterable by nature in ECMAScript 6. The for
-of
loop writes the values 1, 3, and 5 to the browser console in line 2.
Listing 5
for-of-statement.html
Iterator Protocol
The for
-of
loop accesses iterable objects via the iterator protocol. Like many other innovations, it is strongly reminiscent of Python [5]. The new ECMAScript offers generator functions to remove the need for developers to implement the iterator protocol. These are similar to conventional functions, but generate the iterator object.
In Listing 6, the for
-of
loop (lines 8-10) iterates by calling the generator function sum
(lines 1-6). This definition also introduces the function
keyword, which, when immediately followed by an asterisk defines the function being defined as a generator.
Listing 6
generator-functions.html
Within this function, the identically named sum
variable saves an intermediate result; line 2 initializes it with 0
. The for
-of
loop iterates in lines 3-5 against the field passed in by the generator; line 4 adds the current field value to the intermediate result. The yield
keyword returns the updated intermediate result to the next iteration of the loop. The generator starts again for the next loop run after yield
.
The for
-of
loop thus also makes itself useful in array comprehensions (set definitions). Array comprehensions provide a way of generating all fields with a single compact expression. For example, the expression
[for (x of [2, 3]) for(y of [2, 3])Math.pow(x, y)]
generates the field [4, 8, 9, 27]
by means of nested execution of the two for
-of
loops against the expression Math.pow(x, y)
. If the programmer encloses this in parentheses, iterable objects can be created with generator comprehensions. The expression
(for (x of [2, 3]) Math.pow(x, 2))
tells a for
-of
loop to iterate against the values 4 and 8. Destructuring assignments are just as compact and as useful as comprehensions. Objects and fields with simple syntax can be parsed and simultaneously bound to several variables with these special assignments. The statement [b, a] = [a, b]
, for example, swaps the values of the two variables. The statement
var [a,,[b,,[c],d]] =[1, 0, [2, 0, [3, 0], 4], 0]
initializes the variables a
to d
with the values 1
, 2
, 3
, and 4
. The expression to the left of the equals sign is inserted as a mask over the field to the right; it skips items using a comma and follows the field into the depths of the square brackets. The ECMAScript code
var {A: a, B: {C: b}} ={A: 1, B: {C: 2}, D: 3}
similarly initializes the variables a
with 1
and b
with 2
. The programmer can also use such destructuring assignments in the parameter lists of functions and in loops.
Just like PHP, JavaScript from ECMAScript 6 supports default parameters in the parameter list of function definitions. Calling the function
function params(a=0, b=0){ return a+b}
initializes the parameters a
and b
with 0 – if no other values are specified.
ECMAScript 6 provides the spread operator "...
" for processing long parameter lists. A call to rest(1, 2, 3, 4, 5)
in the function
rest(a, b, ...rest){}
causes JavaScript to dump the values 3
, 4
, and 5
into the field rest
. This operator can also be used for unpacking fields. The values of the rest
field are pasted into the expression [1, 2, ...rest, 6]
so that the result reads [1, 2, 3, 4, 5, 6]
.
In addition to the changes discussed so far, ECMAScript 6 provides a large number of new methods and some new objects, such as the Promise
object. A complete description is, however, beyond the scope of this article.
Sample Application
Thanks to ECMAScript 6, the program code for the following sample is simpler than in the past, and you can read it more easily, which helps avoid programming errors. This enhanced clarity is particularly true for the Metronome
class in Listing 7. The methods are defined inline (i.e., in the class body) which saves programming code and makes it easier to assign the class methods.
The syntax in Listing 7 also makes it easier for Java or C++ programmers to come to grips with the otherwise fairly cryptic prototype inheritance in JavaScript. The use of arrow functions in the definition of the two callback functions in line 11 simplifies the code: Arrow functions are written in a single line and lexically bind the special this
variable to the current object, which conveniently eliminates another assignment problem.
Listing 7
Module metronome/metronome.js
Figure 1 shows the sample application in Firefox on Ubuntu 4.12. The metronome plays the beat in a loop. The user enters the desired meter in the number box on the left. The two buttons to the right and left of the box start and stop the metronome.
The audible beats are generated by the Web Audio API [6]. This interface generates and processes audio data using JavaScript in the browser and forwards it to the computer's sound system. It may currently only exist as a W3C draft, but more recent versions of the Firefox and Chrome browsers already have usable implementations.
« Previous 1 2 3 Next »
Buy this article as PDF
(incl. VAT)