Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

The Most Important New JavaScript Elements for Basic Programming

5.00/5 (4 votes)
24 Apr 2020CPOL4 min read 7.2K  
The most important new language elements of JavaScript for basic programming
In this post, you will find a summary of the most important new language elements of JavaScript, which are generally useful for all kinds of basic programming tasks.

There have been many articles about the new language elements introduced to JavaScript by ECMAScript 2015+ (that is, 2015+16+17+18+19+20+...). Typically, in these articles, a great number of new features are presented without taking their relevance into consideration, often with artificial programming examples that do not help to exhibit the potential use of a new feature.

In this post, we only present the most important new language elements, which are generally useful for all kinds of basic programming tasks, in a summarized way.

Block-Scope Variable Declarations with let and const

ES5 did not allow declaring variables the scope of which is a block delimited by a pair of curly braces, { and }, or defined by a for loop. Rather, all variables declared with var, even if declared within a block, have either a function scope or the global scope. The new feature of block-scope variable declarations with let and const allows declaring local variables with a finer-grained scope, which helps avoiding unintended variable duplications and leads to more modular code.

There is only one meaning difference between let and const. Variables declared with const are frozen or immutable, and in this sense constant, while let variables are not. It is preferable to use const for all variables that are not supposed to change their values. Otherwise, or if this is not clear, one should declare the variable with let if it is a block-scoped variable, or with var if it is a global or function-scoped variable.

Arrow Functions with =>

Arrow functions provide a more concise function expression syntax, see Example 1, and allow using JavaScript's this variable from the function’s outer environment (its closure) in their function body, see Example 2.

Example 1

JavaScript
let evens = [0,2,4,6,8];
// instead of evens.map( function (v) {return v+1;})
let odds = evens.map( v => v+1);  // [1,3,5,7,9]

Example 2

JavaScript
this.nums = [1,3,5,8,10,12,15,17];
this.fives = [];
// instead of this.nums.forEach( function (v) {if (v % 5 === 0) this.fives.push(v);}, this)
this.nums.forEach( v => {if (v % 5 === 0) this.fives.push(v);});

For-Of Loops over Iterable Objects

Iterable objects include strings, arrays, array-like objects (e.g., the built-in arguments object or instances of HTMLCollections and NodeList), and instances of the datatype objects TypedArray, Map, and Set, as well as user-defined iterables. For instance:

JavaScript
const divElems = document.getElementsByTagName("div");  // an HTMLCollection
for (let dEl of divElems) {
  console.log( dEl.id);
}

A for-of loop is often more handy than a for loop whenever a counter variable is not needed. As opposed to a forEach loop, a for-of loop allows iterating over HTMLCollections and can be abandoned with break.

Template Literals

... are enclosed by backtick characters (like `... `) instead of double or single quotes and allow a concise syntax for (possibly multi-line) string values resulting from a combination of fixed text parts and variables/expressions. For instance:

JavaScript
const classValues = "card important";
const name = "Joker";
const htmlTemplate = `<div class="${classValues}">
  <p>Hello ${name}!</p>
</div>`

The Spread Operator ...

This allows spreading:

  1. the elements of an iterable collection in places where arguments for function calls or array elements are expected, or
  2. the slots of a JS object in places where name-value pairs are expected.

For instance:

JavaScript
let nums = [3,4,5], otherNums = [1, 2, ...nums];  // [1,2,3,4,5]
// cloning an array
let numsClone = [...nums];
// cloning an object
let book = {title:"JavaScript: The Good Parts"};
let bookClone = {...book};

Destructuring Assignments

Allow a concise syntax for assigning the property values of a JS object or the elements of a JS array to corresponding variables. For instance:

JavaScript
var point1 = [10,5];
var [x,y] = point1;
console.log(`x = ${x} | y = ${y}`);  // x = 10 | y = 5

var person1 = {firstName:"James", lastName:"Bond"};
var {first, last} = person1;
console.log(`first:${first} | last:${last}`);  // first:"James" | last:"Bond"

Use Case 1: Dealing with multiple return values of a function.

JavaScript
function getRectangle () {
  return {width: 50, height: 20};
}
const {a, b} = getRectangle();
drawRectangle( a, b);

Use Case 2: Swapping two variables.

JavaScript
var a = 1, b = 2;
[a,b] = [b,a];
console.log(`a = ${a} | b = ${b}`);  // a = 2 | b = 1

Use Case 3: Cloning arrays with the help of the spread operator.

JavaScript
const list = ['red', 'orange', 'yellow'];
const [...listClone] = list;

Use Case 4: Simplifying functions with parameter records.

A function parameter record allows using named arguments in faction calls instead of argument lists like so:

JavaScript
function displayName( paramRec) {
  alert( paramRec.first + " " + paramRec.last);
};
displayName({first:"James", last:"Bond"});

Using Destructuring, the parameter record fields are assigned to ordinary function parameters, simplifying the function's code:

JavaScript
function displayName({first, last}) {
  alert( first + " " + last);
}
displayName({first:"James", last:"Bond"});

Modules

... are (namespace-protected) libraries that explicitly export those (variable, function and class) names that other modules and web pages can use (as implicitly frozen/const). Modules need to explicitly import names from other modules, while web pages can load modules with a special script element.

For instance, suppose the following code is in a module file lib/math.js.

JavaScript
export function sum( x, y) {return x + y;};
export var pi = 3.141593;

Then, in another JS file, we can import all elements of lib/math.js and use them with:

JavaScript
import * as math from "./lib/math.js";
console.log("2π = " + math.sum(math.pi, math.pi));

Or we can import specific elements of lib/math.js:

JavaScript
import {sum, pi} from "./lib/math.js";
console.log("2π = " + sum(pi, pi));

We can load modules in an HTML file in the following way:

JavaScript
<script type="module" async="async" src="module1.js"></script>
<script type="module" async="async" src="module2.js"></script>

Notice that there is no guarantee which will execute first due to asynchronous loading.

Important New JavaScript Elements for Advanced Programming

  • Classes for simplifying the definition of constructor-based object types (typically with properties having implicit getters and setters for implicit constraint checking)
  • Maps for replacing the use of JS objects as maps
  • Promises for asynchronous method invocation
  • async-await for asynchronous method invocation

Did I forget any important new JS element/feature? Please let me know...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)