Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

JavaScript Language Evolution: Core Features from ES2015 to ES2019

Tech 1

ES2015 (ES6) Enhancements

Class Syntax

ES2015 introduced syntactic sugar over JavaScript's prototype-based inheritance, enabling cleener object-oriented patterns.

class Vehicle {
  constructor(model, year) {
    this.model = model;
    this.year = year;
  }
  
  displayInfo() {
    console.log(`${this.year} ${this.model}`);
  }
}

class ElectricCar extends Vehicle {
  constructor(model, year, range) {
    super(model, year);
    this.range = range;
  }
  
  displayInfo() {
    super.displayInfo();
    console.log(`Range: ${this.range} miles`);
  }
}

const car = new ElectricCar('Model S', 2023, 400);
car.displayInfo();

Module System

The standardized module system uses export and import for dependency management.

// mathUtils.js
export const PI = 3.14159;
export function calculateCircumference(radius) {
  return 2 * PI * radius;
}

// main.js
import { PI, calculateCircumference } from './mathUtils.js';

Arrow Functions

Lexical scoping of this eliminates the need for explicit binding in callbacks.

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(n => n * 2);

// Lexical this binding
const counter = {
  value: 0,
  increment: function() {
    setInterval(() => {
      this.value++;
      console.log(this.value);
    }, 1000);
  }
};

Default Parameters

Function parameters can specify fallback values directly in the signature.

function createUser(username = 'guest', role = 'viewer') {
  return { username, role };
}

// Prevents falsy value bugs
function multiply(a, b = 1) {
  return a * b;
}
multiply(5, 0); // Returns 0, not 5

Template Literals

Interpolated strings support embedded expressions and multi-line content.

const user = { first: 'Jane', last: 'Doe' };
const greeting = `Welcome, ${user.first} ${user.last}!`;

const html = `
  <div>
    <h1>${greeting}</h1>
  </div>
`;

Destructuring Assignment

Extract values from arrays and objects into distinct variables.

// Array destructuring
const coords = [10, 20, 30];
const [x, y, z] = coords;

// Object destructuring
const product = { id: 101, name: 'Laptop', price: 999 };
const { name, price } = product;

// Nested destructuring
const response = { data: { user: { email: 'test@example.com' } } };
const { data: { user: { email } } } = response;

Spread Syntax

Expand iterable elements or object properties into individual elements.

// Array spreading
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];

// Object spreading
const defaults = { theme: 'dark', fontSize: 14 };
const settings = { ...defaults, fontSize: 16 };

// Function arguments
function sum(a, b, c) {
  return a + b + c;
}
const values = [1, 2, 3];
sum(...values);

Property Shorthand

Object literals infer property names from variable identifiers.

const latitude = 40.7128;
const longitude = -74.0060;

const location = { latitude, longitude };
// Equivalent to: { latitude: latitude, longitude: longitude }

Promise Objects

Native asynchronous programming abstraction replacing callback patterns.

function fetchData(url) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then(response => response.json())
      .then(data => resolve(data))
      .catch(error => reject(error));
  });
}

fetchData('/api/user')
  .then(user => console.log(user))
  .catch(err => console.error(err));

Block-Scoped Declarations

let and const provide lexical scoping within blocks, unlike function-scoped var.

if (true) {
  let blockScoped = 'visible only here';
  const constant = 'cannot reassign';
}
// blockScoped and constant are not accessible here

ES2016 (ES7) Additions

Array.prototype.includes()

Determines array membership with a boolean return value.

const fruits = ['apple', 'banana', 'cherry'];
const hasApple = fruits.includes('apple'); // true
const index = fruits.indexOf('apple'); // 0

Exponentiation Operator

Mathematical power operator as an alternative to Math.pow().

const cubed = 3 ** 3; // 27
const square = Math.pow(4, 2); // 16

ES2017 (ES8) Features

Async Functions

Syntactic sugar for Promise-based asynchronous operations.

async function getUserData(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Fetch failed:', error);
  }
}

Object Value Extraction

Object.values() returns enumerable property values.

const config = { host: 'localhost', port: 3000, ssl: true };
const values = Object.values(config); // ['localhost', 3000, true]

Object Entry Iteration

Object.entries() returns key-value pairs for iteration.

const scores = { math: 95, science: 88, english: 92 };
for (const [subject, score] of Object.entries(scores)) {
  console.log(`${subject}: ${score}`);
}

String Padding

padStart() and padEnd() normalize string lengths.

const invoice = '42';
const padded = invoice.padStart(6, '0'); // '000042'

const description = 'Item';
const aligned = description.padEnd(10, '.'); // 'Item......'

Trailing Commas

Function parameter lists and calls tolerate trailing commas.

function setup(
  host,
  port,
  protocol, // Trailing comma allowed
) {
  // Implementation
}

Property Descriptors

Object.getOwnPropertyDescriptors() retrieves all property descriptors.

const target = {
  name: 'example',
  get value() { return 42; }
};
const descriptors = Object.getOwnPropertyDescriptors(target);

Shared Memory Operations

SharedArrayBuffer and Atomics enable concurrent memory access patterns.

const buffer = new SharedArrayBuffer(1024);
const view = new Int32Array(buffer);
Atomics.store(view, 0, 123);
const value = Atomics.load(view, 0);

ES2018 (ES9) Capabilities

Asynchronous Iteration

for-await-of loops handle asynchronous iterators.

async function* asyncGenerator() {
  yield await Promise.resolve(1);
  yield await Promise.resolve(2);
}

(async () => {
  for await (const num of asyncGenerator()) {
    console.log(num);
  }
})();

Promise Completion Handling

finally() executes cleanup logic regardless of settlement state.

fetch('/api/data')
  .then(response => response.json())
  .catch(error => console.error(error))
  .finally(() => {
    console.log('Request completed');
  });

Rest and Spread for Objects

Destructuring and spreading work with object properties.

const { id, ...metadata } = { id: 1, name: 'Doc', size: '2MB' };
const merged = { ...metadata, timestamp: Date.now() };

Regular Expression Enhancements

Named Capture Groups:

const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = datePattern.exec('2023-12-25');
console.log(match.groups.year); // '2023'

Lookbehind Assertions:

const pricePattern = /(?<=\$)\d+\.?\d*/;
const price = pricePattern.exec('Price: $49.99')[0]; // '49.99'

DotAll Flag:

const multiline = /hello.world/s;
multiline.test('hello\nworld'); // true

Unicode Property Escapes:

const greekLetter = /\p{Script=Greek}/u;
greekLetter.test('Ω'); // true

ES2019 (ES10) Improvements

Array Flattening

flat() collapses nested arrays; flatMap() maps then flattens.

const nested = [1, [2, 3], [4, [5, 6]]];
const flattened = nested.flat(2); // [1, 2, 3, 4, 5, 6]

const sentences = ['Hello world', 'Goodbye moon'];
const words = sentences.flatMap(s => s.split(' '));

String Trimming

trimStart() and trimEnd() remove whitespace from specific ends.

const input = '   padded   ';
const leftTrimmed = input.trimStart(); // 'padded   '
const rightTrimmed = input.trimEnd(); // '   padded'

Object from Entries

Convert key-value pairs into objects, inverting Object.entries().

const pairs = [['x', 10], ['y', 20]];
const point = Object.fromEntries(pairs); // { x: 10, y: 20 }

const map = new Map([['a', 1], ['b', 2]]);
const obj = Object.fromEntries(map);

Symbol Descriptions

Access symbol descriptions via the description property.

const sym = Symbol('unique identifier');
console.log(sym.description); // 'unique identifier'

Match All Iterations

matchAll() returns an iterator of all matches including capture groups.

const text = 'test1test2';
const regex = /t(e)(st(\d?))/g;
const matches = [...text.matchAll(regex)];
// Access individual capture groups per match

Function Source Preservation

toString() returns exact source code including comments and whitespace.

function /* note */ example() {}
console.log(example.toString());
// Includes comment in output

Optional Catch Binding

Omit error parameter when exception details are unnecessary.

try {
  riskyOperation();
} catch {
  handleErrorGenerically();
}

BigInt Type

Arbitrary-precision integers beyond Number.MAX_SAFE_INTEGER.

const huge = 9007199254740993n;
const result = huge + 1n;
console.log(result === 9007199254740994n); // true

Global This

Universal global object reference acros environments.

const globalObject = globalThis;
// Works in browsers, Node.js, and web workers

Dynamic Imports

Programmatic module loading returning promises.

async function loadModule() {
  const { utility } = await import('./utils.js');
  utility();
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.