Modern JavaScript Features in ES7 and ES8

ES7 Features

Array.prototype.includes()

The includes() method determines whether an array contains a specified element, returning true or false.

Basic Syntax:

const elements = ['x', 'y', 'z'];
console.log(elements.includes('x')); // true
console.log(elements.includes('w')); // false

Specifying Start Index:

const letters = ['a', 'b', 'c', 'd'];
console.log(letters.includes('b'));      // true
console.log(letters.includes('b', 1));   // true
console.log(letters.includes('b', 2));   // false

Comparison with indexOf():

const data = ['p', 'q', 'r'];
console.log(data.includes('p'));                 // true
console.log(data.indexOf('p') !== -1);           // true

const numbers = [5, 6, 7];
const target = 5;
console.log(numbers.includes(target));           // true
console.log(numbers.indexOf(target));            // 0

Handling Edge Cases:

const testArray = [1, 0, 3, 4];
console.log(testArray.includes(-0));             // true
console.log(testArray.indexOf(-0));              // 1

Limitations with Complex Types:

const complexArray = [1, [2, 3], 4];
console.log(complexArray.includes([2, 3]));      // false
console.log(complexArray.indexOf([2, 3]));       // -1

NaN Handling Differences:

const sampleArray = [1, NaN, 2, 3];
console.log(sampleArray.indexOf(NaN));            // -1
console.log(sampleArray.includes(NaN));          // true

Use includes() when you only need to check for element existence. Use indexOf() when you need the element's position.

Exponentiation Operator

Basic Usage:

const result = 3 ** 2;
console.log(result); // 9
// Equivalent to Math.pow(3, 2)

Compound Assignment:

let base = 4;
base **= 3;
console.log(base); // 64

ES8 Features

Async/Await

Asynchronous functions provide cleaner syntax for handling promises.

Function Declaration Forms:

async function fetchData() {}
const fetchData = async function() {};
const obj = { async fetchData() {} };
const fetchData = async () => {};

Return Values:

// Returns Promise
const delayedValue = async function() {
    return new Promise((resolve) => {
        setTimeout(() => resolve('completed'), 500);
    });
};

delayedValue().then(console.log); // 'completed'

// Returns Synchronous Value
const immediateValue = async function() {
    return 'ready';
};
immediateValue().then(console.log); // 'ready'

Error Handling:

// Promise Error Examples
const failingPromise = new Promise((_, reject) => {
    setTimeout(() => reject(new Error('Operation failed')), 300);
});

failingPromise.catch(err => console.log(err.message));

// Async Function Error Handling
const asyncWithError = async () => {
    throw new Error('Async error');
};

asyncWithError().catch(err => console.log(err.message));

Sequential Execution:

const getUser = async () => {
    try {
        const profile = await fetchProfile();
        const settings = await fetchSettings();
        return { profile, settings };
    } catch (error) {
        console.error('Failed:', error);
    }
};

Parallel Execution:

const loadData = async () => {
    const [userData, configData] = await Promise.all([
        fetchUserData(),
        fetchConfigData()
    ]);
    return { userData, configData };
};

Comparison with Generators:

// Generator Example
function* generateSequence() {
    yield fetchFirst();
    yield fetchSecond();
    return 'done';
}

// Equivalent Async/Await
const asyncSequence = async () => {
    const first = await fetchFirst();
    const second = await fetchSecond();
    return 'done';
};

Object.entries()

Returns an array of key-value pairs from an object.

Basic Usage:

const obj = { first: 1, second: 2 };
console.log(Object.entries(obj)); // [['first', 1], ['second', 2]]

const arr = [10, 20];
console.log(Object.entries(arr)); // [['0', 10], ['1', 20]]

Key Order:

const unordered = { 5: 'e', 2: 'b', 9: 'i' };
console.log(Object.entries(unordered)); 
// [['2', 'b'], ['5', 'e'], ['9', 'i']]

Creating Map from Object:

const source = { key1: 'value1', key2: 'value2' };
const mapFromEntries = new Map(Object.entries(source));
console.log(mapFromEntries.get('key1')); // 'value1'

Custom Implementation:

function customEntries(inputObject) {
    const pairs = [];
    for (const key of Object.keys(inputObject)) {
        pairs.push([key, inputObject[key]]);
    }
    return pairs;
}

Object.values()

Returns an array containing object property values.

Usage:

const sample = { alpha: 100, beta: 200 };
console.log(Object.values(sample)); // [100, 200]

Comparison with Object.keys():

const data = { x: 'ex', y: 'why' };
console.log(Object.keys(data));   // ['x', 'y']
console.log(Object.values(data)); // ['ex', 'why']

String Padding

padStart() and padEnd():

console.log('ABC'.padStart(8));        // '     ABC'
console.log('XYZ'.padEnd(8, '-'));     // 'XYZ-----'
console.log('LongString'.padStart(5)); // 'LongString'

Object.getOwnPropertyDescriptors()

Returns all own property descriptors of an object.

Usage:

const example = {
    id: 100,
    label: 'test',
    get computedProp() {
        return this.id * 2;
    }
};

console.log(Object.getOwnPropertyDescriptors(example));

Comparison with getOwnPropertyDescriptor():

console.log(Object.getOwnPropertyDescriptor(example, 'id'));
// Returns descriptor only for 'id' property

Trailing Commas in Function Parameters

Functions can have trailing commas in parameter lists.

Example:

const exampleFunction = (
    paramOne,
    paramTwo,
    paramThree,
) => {
    return paramOne + paramTwo + paramThree;
};

Decorators

Decorators are functions that modify class or method behavior.

Basic Class Decorator:

function addMetadata(target) {
    target.meta = 'additional data';
}

@addMetadata
class SampleClass {}

console.log(SampleClass.meta); // 'additional data'

Decorator with Parameters:

function tagWithLabel(labelText) {
    return function(target) {
        target.label = labelText;
    };
}

@tagWithLabel('important')
class TaggedClass {}

Method Decorator:

class ExampleClass {
    @logExecution
    processData() {
        console.log('Processing data');
    }
}

function logExecution(target, methodName, descriptor) {
    const original = descriptor.value;
    descriptor.value = function(...args) {
        console.log(`Executing ${methodName}`);
        return original.apply(this, args);
    };
    return descriptor;
}

Execution Order:

class MultiDecoratorClass {
    @decoratorOne()
    @decoratorTwo()
    sampleMethod() {}
}

Decorators execute during compilation, not at runtime. They cannot be applied to functions due to hoisting behavior.

Tags: javascript ES7 ES8 ecmascript Modern JavaScript

Posted on Mon, 18 May 2026 11:30:22 +0000 by lookee