Some features that every JavaScript developer should know in 2025 (part 3)

Published on

JS symbol

After publishing the article "Some features that every JavaScript developer should know in 2025 (continued)", I have compiled a new list of other cool features (old and new) that I am going to share with you.

Function "named" arguments

Have you ever seen a function with tons of arguments, where some of them might have default values? For example, something like this:

function connectToDb( dbUrl, username, password, encoding = 'utf-8', portNumber = 3000, timeout = 30 ) { // do something... }

Now, you want to pass a custom value for argument timeout, for example, 20. For you this means an unpleasant situation where you have to pass all the arguments that come before timeout, even the ones that have a default value:

connectToDb('jdbc:mysql://some_host', 'some_username', 'some_pass', 'utf-8', 3000, 20);

We probably don't want to pass the default values 'utf-8' and 3000 again by code duplication, since the default values are already set. So, how to solve this problem when we want to override only some arguments?

This problem can be solved by using the object destructuring and default value syntax:

function connectToDb( dbUrl, username, password, { encoding = 'utf-8', portNumber = 3000, timeout = 30 } = {} ) { console.log(dbUrl, username, password, encoding, portNumber, timeout); // do something... } connectToDb('jdbc:mysql://some_host', 'some_username', 'some_pass', { timeout: 20 }); // 'jdbc:mysql://some_host', 'some_username', 'some_pass', 'utf-8', 3000, 20 connectToDb('jdbc:mysql://some_host', 'some_username', 'some_pass'); // 'jdbc:mysql://some_host', 'some_username', 'some_pass', 'utf-8', 3000, 30

Although some other languages like PHP or Dart support named function arguments natively and have a more elegant syntax, this works very well and it's the closest thing to named arguments that you can imagine.

Dynamic code execution via Function objects

I think many of us have heard about eval() and some even used for code execution. Actually eval() is a terrible way to execute code, and you probably shouldn't use it. The reason is because eval() can also access the local variables, which means it's less safe and also runs slower:

function f() { let a = 1; eval("++a"); console.log(a); // 2 } f();

The correct way of code execution is by constructing Function object and calling it. Function constructor accepts one or more arguments. If one argument is passed, it's interpreted as a function body, if multiple arguments are passed, the last one is interpreted as a function body, the rest are interpreted as argument definitions. Here are some examples:

{ // A simple function without arguments const f1 = new Function('console.log("f1")'); // A function with arguments and return statement const f2 = new Function('a', 'b', 'return a * b;'); // A function with default arguments and return statement const f3 = new Function('a = 1', '{b = 2, c = 3} = {}', 'd = 4', 'return [a, b, c, d];'); let a = 1; // A function that attempts to access a local variable const f4 = new Function('++a'); f1(); // "f1" console.log(f2(6, 8)); // 48 console.log(f3()); // [1, 2, 3, 4] console.log(f3(10, { c: 30 })); // [10, 2, 30, 4] f4(); // error since "a" is not a global variable }

Warning, any code execution has potential risks, and you should never execute any untrusted code.

Reading and writing cookies via cookieStore

Many people who have dealt with cookies with JavaScript know how painful and complicated are cookie manipulations (parsing, saving) via document.cookie. This is why cookieStore was added as part of the Cookie Store API. With cookieStore cookie manipulations become a breeze. Here are simple examples of using cookieStore.get(), cookieStore.set(), cookieStore.delete() and cookieStore.getAll():

// A basic way of setting as key and value await cookieStore.set('cookie1', 'Cookie one'); // An advanced way of setting via object await cookieStore.set({ name: 'cookie2', value: 'Cookie two', expires: new Date('2026-05-27T20:00:00.000Z'), }); console.log(await cookieStore.get('cookie1')); // { name: 'cookie1', value: 'Cookie one', expires: null, ... } console.log(await cookieStore.get('cookie2')); // { name: 'cookie2', value: 'Cookie one', expires: 1779912000000, ... } console.log(await cookieStore.getAll()); // [{ name: ..., value: ..., ...}, {...}, ... ] await cookieStore.delete('cookie1'); console.log(await cookieStore.get('cookie1')); // null

This feature is not supported in Firefox yet, so don't use it in production code without polyfills.

Exponentiation operator

Some people might not know but JavaScript has operator ** which raises a number to some power:

console.log(3 ** 4); // 3 * 3 * 3 * 3 = 81, the same as Math.pow(3, 4) console.log(0.25 ** -0.5) // 2 console.log(3n ** 4n); // 81n

Reverse array methods

JavaScript arrays methods typically iterate from left to right, such as find() or findIndex(). However, modern JavaScript also supports methods that iterate from right to left:

console.log([1, 2, 3].findIndex((x) => x % 2 === 1)); // 0 console.log([1, 2, 3].findLastIndex((x) => x % 2 === 1)); // 2 console.log([1, 2, 3].find((x) => x % 2 === 1)); // 1 console.log([1, 2, 3].findLast((x) => x % 2 === 1)); // 3 console.log([1, 2, 1].indexOf(1)); // 0 console.log([1, 2, 1].lastIndexOf(1)); // 2 console.log([1, 2, 3].reduce((acc, cur) => acc + cur, '')); // "123" console.log([1, 2, 3].reduceRight((acc, cur) => acc + cur, '')); // "321"

Fast number truncation

In JavaScript numbers can be truncated to integers without using Math.trunc() by using bitwise operations. This can improve performance because we make the code more inlined by avoiding the overheads of the function calls. Note that this will not work correctly for numbers that have more than 32 bits (less than / equal to -2147483649 or greater than / equal to 2147483648), so use it with caution.

This works because when you apply bitwise operations to numbers, they are converted to 32-bit integers. Here are examples:

console.log(10.3 | 0); // 10 console.log(10.3 ^ 0); // 10 console.log(10.3 << 0); // 10 console.log(~~10.3); // 10 console.log(Math.trunc(10.3)); // 10 console.log(-10.3 | 0); // -10, works for negative numbers as well console.log(Math.trunc(-10.3)); // -10 console.log(2147483647.1 | 0); // 2147483647 console.log(Math.trunc(2147483647.1)); // 2147483647 console.log(-2147483648.1 | 0); // -2147483648 console.log(Math.trunc(-2147483648.1)); // -2147483648 console.log(2147483648.1 | 0); // -2147483648, doesn't work correctly console.log(Math.trunc(2147483648.1)); // 2147483648 console.log(-2147483649.1 | 0); // 2147483647, doesn't work correctly console.log(Math.trunc(-2147483649.1)); // -2147483649




Read previous


This site uses cookies. By continuing to use this website, you agree to their use. To find out more, including how to control cookies, see here: Privacy & cookies.