A Preview of ECMAScript 6 Succinctly

The following is an excerpt from ECMAScript 6 Succinctly, written by Matthew Duffield. Look for this upcoming title to be added in late June to the Succinctly series—Syncfusion’s free library of pithy technology books.

Introducing ES6

ECMAScript 6 (ES6), also known as ECMAScript 2015, brings new functionality and features to the table that developers have been wanting for a long time. The wait is over, and you can now develop all of these features. The really good news is that you can also target browsers that don’t even support ES6 yet by using a transpiler. A compiler translates one language to another, such as C# to MSIL, while a transpiler converts one version of a language to another, such as ES6 to ES5.

Constants

Most modern languages provide some method of defining a constant. This ensures that the value of the variable never changes and is a great optimization usage for values you know will never change in your applications.  


Let’s take a look at several examples of constants:

Code Listing 5

const PI = 3.141593;
console.log(PI);

The code produces the following output in Sublime using Ctrl+B for Windows or Cmd+B for Mac:

Code Listing 6

3.141593

Note: Unless indicated otherwise, we will use Sublime as the editor of choice for code snippets. In the Git repository, you will find the corresponding snippets in their own chapter.

Now, let’s try and re-assign a value to the PI variable. We can do this by adding the following lines to the editor:

Code Listing 7

PI = 22;
console.log(PI);

Trying to run the previous example will produce a syntax error. The transpiler is smart enough to give us the reason why. Take a look at the following image:


You can see in Figure 2 that since PI was declared as a constant, it is considered read-only. This is good and the error description is very clear.

Note: The const keyword can only be used in block scope areas. We will look at block scopes in the next section.

Scoping

Previously, JavaScript developers had to deal with hoisting when using the var keyword. At runtime, any variable that is declared will be hoisted up to the top of the executing context. Let’s look at several examples of how the var keyword is handled at runtime:

Code Listing 8

var submit = function() {
  var x = "foo"; 
if (x == "foo") { var y = "bar"; } console.log(x); console.log(y); } submit();

The code produces the following output:

Code Listing 9

foo
bar

As you can see from the output, both x and y variables are available at the function level. This is known as hoisting regardless of the logical blocks.

With the let keyword, this is now different. Let’s modify the previous code listing, but use the let keyword when declaring the y variable:

Code Listing 10

var submit = function() {

  var x = "foo"; 

  if (x == "foo") {

    let y = "bar";

  }

  console.log(x);
  console.log(y);

}

submit();

The code produces the following output in Chrome after clicking on the Run button:

Code Listing 11

"ReferenceError: y is not defined

This output is actually pretty good in that it lets us know that we are trying to reference a variable that is out of scope.

The following example demonstrates how the let operator works inside for-loops:

Code Listing 12

let shoppingCart = [

  {id: 0, product: "DVD", price: 21.99},

  {id: 1, product: "CD", price: 11.99}

]; 

for (let i = 0; i < shoppingCart.length; i++) {

  let item = shoppingCart[i];
  console.log("Item: " + item.product + " - Price: " + item.price);

}

Let us look at the output that is produced:

Code Listing 13

Item: DVD - Price: 21.99
Item: CD - Price: 11.99

As you can see, we still get the expected behavior, but the item variable has a scope boundary of the for-loop.

When using a transpiler, this alone will help mitigate many scoping issues that were error-prone in ES5 with hoisting.

Enhanced Regular Expressions

Two new flags are introduced in ES6 for regular expressions

  • /y
  • /u

Sticky flag

The new /y sticky flag allows you to create sticky searches; it anchors each match of a regular expression to the end of the previous match.

Let’s look at the following example:
Code Listing 14
var text =
'First line\nsecond line';
var regex =
/^(\S+) line\n?/y;
 
var match =
regex.exec(text);
console.log(match[1]);        // logs 'First'
console.log(regex.lastIndex); // logs
'11'
 
var match2 =
regex.exec(text);
console.log(match2[1]);       // logs'Second'
console.log(regex.lastIndex); // logs '22'
 
var match3 =
regex.exec(text);
console.log(match3 ===
null); //
logs 'true'

Note: This example will only work in Microsoft Edge or Firefox.

We start out with a simple string in the text variable. Next, we define our regular expression. As you can see, we are looking for matches that end with “line” and possibly a new line. We then execute the regular expression and grab the first match which contains the value First and also logs the lastIndex position.

We run the exec method on the text variable again and it continues from the lastIndex position and finds the “Second” match. The lastIndex position is updated and logged.

Finally, we run the exec method a third time, and it returns null, indicating no more matches were found.

The main use case for this new flag is tokenizing, where you want each match to immediately follow its predecessor.

The following is an example of tokenizing a string:

Code Listing 15

const TOKEN = /\s*(\+|[0-9]+)\s*/y; 

function tokenize(TOKEN_REGEX, str) {

  let result = [];
  let match;

  while (match = TOKEN_REGEX.exec(str)) {

    result.push(match[1]);

  }

  return result;

} let result = tokenize(TOKEN, '3 + 4'); console.log(JSON.stringify(result));

Note: This example will only work in Microsoft Edge or Firefox.

Here is the output it produces:

Code Listing 16

["3","+","4"]

Although this is a contrived example, you can see where this could come in very handy when wanting to tokenize strings.

Unicode

The /u flag puts the regular expression into a special Unicode mode. This mode has two features:

  • You can use Unicode code point escape sequences, such as \u{1F42A}, for specifying characters via code points. Normal Unicode escapes, such as \u03B1, only have a range of four hexadecimal digits.
  • “Characters” in the regular expression pattern and the string are code points (not UTF-16 code units).
Let's take a look at some examples:

Code Listing 17

console.log('\u{1F680}' === '\uD83D\uDE80');
let codepoint = "\u{1F680}";
console.log(codepoint);

Executing this produces the following result:

Code Listing 18

True
🚀

The first line of code demonstrates comparing a Unicode code point against two normal Unicode escapes. The second and third lines simply demonstrate how you can render the Unicode code point. 

Note: Neither the /y nor /u flags are supported in all browsers. These samples were used in Firefox but could have also been run in Microsoft Edge.

Loading