DEV Community

Cover image for 25 Unnoticeable Features of JavaScript
M Mainul Hasan
M Mainul Hasan

Posted on • Originally published at webdevstory.com

25 Unnoticeable Features of JavaScript

Often, as developers, we write similar types of code, falling into a pattern that, while comfortable, can sometimes feel mundane.

However, the world of JavaScript is vast, filled with advanced features that, when discovered and used, can transform our development work into something much more exciting and fulfilling.

In this guide, we will unveil 25 advanced JavaScript features that promise not just to reveal these hidden gems but also to elevate your mastery of JavaScript to unprecedented levels.

Let’s embark on this journey of discovery together, integrating JavaScript’s advanced capabilities into our coding repertoire to create more efficient, elegant, and powerful applications. It’s time to infuse our development tasks with a newfound sense of fun and creativity.

1 — Labels for Loop and Block Statements

JavaScript allows labeling loops and block statements, enabling precise control with break and continue.

outerLoop: for (let i = 0; i < 5; i++) {
    innerLoop: for (let j = 0; j < 5; j++) {
        if (i === 2 && j === 2) break outerLoop;
        console.log(`i=${i}, j=${j}`);
    }
}
Enter fullscreen mode Exit fullscreen mode

2 — Comma Operator

The comma operator allows multiple expressions to be evaluated in a sequence, returning the last expression’s result.

let a = (1, 2, 3); // a = 3
Enter fullscreen mode Exit fullscreen mode

3 — Tagged Template Literals Beyond String Formatting

Beyond creating strings, tagged templates can be used for DSLs (Domain Specific Languages), sanitizing user input, or localization.

function htmlEscape(strings, ...values) {
    // Example implementation
}
Enter fullscreen mode Exit fullscreen mode

4 — Function Declarations Inside Blocks

Though not recommended, JavaScript allows function declarations inside blocks, which can lead to different behaviors in non-strict mode.

if (true) {
    function test() { return "Yes"; }
} else {
    function test() { return "No"; }
}
test(); // Behavior varies depending on the environment
Enter fullscreen mode Exit fullscreen mode

5 — void Operator

The void operator evaluates any expression and then returns undefined, useful for hyperlinks with JavaScript.

void (0); // returns undefined
Enter fullscreen mode Exit fullscreen mode

6 — Bitwise Operators for Quick Math

Bitwise operators, like | and &, can perform some math operations much faster, though at the cost of readability.

let floor = 5.95 | 0; // Fast way to do Math.floor(5.95)
Enter fullscreen mode Exit fullscreen mode

7 — with Statement for Working with Objects

The with statement extends the scope chain for a block, allowing you to write shorter code. However, it's not recommended due to readability and performance concerns.

with(document.getElementById("myDiv").style) {
    background = "black";
    color = "white";
}
Enter fullscreen mode Exit fullscreen mode

Skillshare Course on JavaScript Development by Christian Heilmann

Sharpen your JavaScript skills with Christian Heilmann’s — start writing cleaner, faster, and better code today!

8 — Automatic Semicolon Insertion (ASI)

JavaScript tries to fix missing semicolons, but relying on it can lead to unexpected results.

let x = 1
let y = 2
[x, y] = [y, x] // Without proper semicolons, this could fail
Enter fullscreen mode Exit fullscreen mode

9 — in Operator for Property Checking

Check if an object has a property without accessing its value directly.

"toString" in {}; // true
Enter fullscreen mode Exit fullscreen mode

10 — instanceof vs. typeof

instanceof checks the prototype chain, while typeof returns a string indicating the type of the unevaluated operand.

function Person() {}
let person = new Person();
console.log(person instanceof Person); // true
console.log(typeof person); // "object"
Enter fullscreen mode Exit fullscreen mode

11 — Block-Level Functions in ES6

ES6 allows functions to be block-scoped, similar to let and const.

{
    function test() {
        return "block scoped";
    }
}
console.log(typeof test); // "function" in non-strict mode, "undefined" in strict mode
Enter fullscreen mode Exit fullscreen mode

12 — Debugger Statement

Use the debugger statement to pause execution and open the debugger.

function problematicFunction() {
    debugger; // Execution pauses here if the developer tools are open
}
Enter fullscreen mode Exit fullscreen mode

13 — eval() for Dynamic Code Execution

eval executes a string as JavaScript code but comes with significant security and performance implications.

eval("let a = 1; console.log(a);"); // 1
Enter fullscreen mode Exit fullscreen mode

InMotion Hosting Promotional Web Hosting Plans

Find the right hosting solution for your projects with InMotion Hosting’s range of plans, from shared to VPS, and dedicated servers.

14 — Non-standard __proto__ Property

While __proto__ is widely supported for setting an object's prototype, it's non-standard. Use Object.getPrototypeOf() and Object.setPrototypeOf() instead.

let obj = {};
obj.__proto__ = Array.prototype; // Not recommended
Enter fullscreen mode Exit fullscreen mode

15 — document.write() for Direct Document Editing

document.write() directly writes to the HTML document, but using it can have negative implications, especially for loading external scripts synchronously.

document.write("<h1>Hello World!</h1>");
Enter fullscreen mode Exit fullscreen mode

16 — Chained Assignment

JavaScript allows for chained assignments, which can assign a single value to multiple variables in one statement.

let a, b, c;
a = b = c = 5; // Sets all three variables to the value of 5
Enter fullscreen mode Exit fullscreen mode

17 — The in Operator for Property Existence

The in operator checks if a property exists within an object without accessing the property value.

const car = {
    make: 'Toyota',
    model: 'Corolla'
};
console.log('make' in car); // true
Enter fullscreen mode Exit fullscreen mode

18 — Object Property Shorthand

When assigning properties to an object, if the property name is the same as the variable name, you can use the shorthand.

const name = 'Alice';
const age = 25;
const person = { name, age };
Enter fullscreen mode Exit fullscreen mode

19 — Default Parameter Values and Destructuring Combined

You can combine default parameter values with destructuring in function parameters for more readable and flexible function definitions.

function createPerson({ name = 'Anonymous', age = 0 } = {}) {
   console.log(`Name: ${name}, Age: ${age}`);
}
createPerson({ name: 'Alice' }); // Name: Alice, Age: 0
createPerson(); // Name: Anonymous, Age: 0
Enter fullscreen mode Exit fullscreen mode

20 — Using Array.fill() to Initialize Arrays

Quickly initialize an array with a specific value using the fill() method.

const initialArray = new Array(5).fill(0); // Creates an array [0, 0, 0, 0, 0]
Enter fullscreen mode Exit fullscreen mode

Ergonomic workspace setup with a laptop on a desk illuminated by a LED desk lamp indicating 500 lux brightness at 35.4 inches, surrounded by books and office supplies.

Optimize your workspace for productivity and comfort with adjustable LED lighting, creating an ideal environment for focused work sessions.

21 — Array.includes() for Presence Check

Easily check for the presence of an element within an array with the includes() method, which is more readable than using indexOf().

const fruits = ['apple', 'banana', 'mango'];
console.log(fruits.includes('banana')); // true
Enter fullscreen mode Exit fullscreen mode

22 — Destructuring Aliases

When destructuring an object, you can assign properties to variables with different names using aliases.

const obj = { x: 1, y: 2 };
const { x: newX, y: newY } = obj;
console.log(newX); // 1
Enter fullscreen mode Exit fullscreen mode

23 — Nullish Coalescing Operator for Default Values

Use ?? to provide default values only when dealing with null or undefined, not other falsy values like

const count = 0;
console.log(count ?? 10); // 0, because count is not null or undefined
Enter fullscreen mode Exit fullscreen mode

24 — Dynamic Function Names

Create functions with dynamic names using computed property names in object literals.

const dynamicName = 'func';
const obj = {
    [dynamicName]() {
        return 'Dynamic Function Name!';
    }
};
console.log(obj.func()); // "Dynamic Function Name!"
Enter fullscreen mode Exit fullscreen mode

25 — Private Class Fields

Use the hash # prefix to define private fields in a class, which cannot be accessed from outside the class.

class Counter {
    #count = 0;

    increment() {
        this.#count++;
    }

    getCount() {
        return this.#count;
    }
}
Enter fullscreen mode Exit fullscreen mode

Wrap Up

As we conclude our exploration of the 25 advanced JavaScript features, JavaScript’s arsenal is both vast and profoundly capable.

Each feature we’ve delved into opens up new avenues for solving coding challenges, akin to adding an innovative tool to our toolkit.

This not only enhances our ability to craft solutions creatively and efficiently but also underscores the dynamic versatility of JavaScript.

These advanced features spotlight the critical role of continuous learning in the realm of web development.

Embracing these nuances and integrating them into our daily coding practices allows us to refine our skills and contribute to the evolution of web technologies.

Remember, the path to mastering JavaScript is a continuous journey, where every line of code presents an opportunity to uncover something extraordinary.

Let’s keep pushing the boundaries of what we can achieve with JavaScript, staying curious and open to the endless possibilities that lie ahead.

Support Our Tech Insights

Buy Me A Coffee

Donate via PayPal button

Note: Some links on this page might be affiliate links. If you make a purchase through these links, I may earn a small commission at no extra cost to you. Thanks for your support!

Top comments (41)

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Beware...

x | 0 is not the same as Math.floor(x), neither is ~~x - as is sometimes written.

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

They are the same as Math.trunc(x)

Collapse
 
mellen profile image
Matt Ellen • Edited

for numbers up to 32 bits. bigger than 32 bits they are different.

developer.mozilla.org/en-US/docs/W...

Collapse
 
fpaghar profile image
Fatemeh Paghar • Edited

one more feature of JS
Memoization for Performance Optimization
Memoization is a technique used to optimize the performance of functions by caching the results of expensive function calls and returning the cached result when the same inputs occur again. This can significantly reduce redundant calculations, especially in recursive or computationally intensive functions.

function fibonacci(n, memo = {}) {
  if (n in memo) return memo[n];
  if (n <= 1) return 1;
  return memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
}
console.log(fibonacci(10)); // Example usage

Enter fullscreen mode Exit fullscreen mode

By memorizing function results, developers can enhance the efficiency of their code, particularly in scenarios where functions are repeatedly called with the same inputs, as it minimizes unnecessary computation. This aligns with the theme of exploring advanced JavaScript features to improve code performance and productivity.

Collapse
 
jonrandy profile image
Jon Randy 🎖️

This isn't a feature of JS, rather a general programming technique.

Collapse
 
fpaghar profile image
Fatemeh Paghar

Maybe ...
But there is memoization in Rect to prevent extra rendering with usecallback and use Memo. Maybe this technique is implemented as a feature.

Thread Thread
 
jonrandy profile image
Jon Randy 🎖️

React is built from plain JS

Collapse
 
eshimischi profile image
eshimischi

Not a feature of JS itself, just a practice developed over the years, do not confuse

Collapse
 
aj-esh profile image
Ajeesh Sunil

Explained it gre8 though, in easy mode

Collapse
 
jankapunkt profile image
Jan Küster

Aaaah nice, labelled break and continue, the fork and spoon of spaghetti code 🍝😄

Collapse
 
efpage profile image
Eckehard

break isn´t as bad as goto, there are situations where it can be most useful and not too much confusing. Adding some flags to break out a loop is not much clearer and has the same effect.

But it is worth to mention that in JS break without labels always breaks out to the outermost loop, so using labels can be a real life saver.

Collapse
 
htho profile image
Hauke T.

Nice article. It would bei nice if you included links to the according MDN articles.

Your coclusion bothers me: eval, with, document.write() and __proto__ don't belong in anyones "toolkit". But: I'd really enjoy an an article named "Javascripts forbidden fruits".

If you care about your fellow developers and your future self - reading your Code, you also should avoid Labels, the comma operator, functions in blocks, void and any bitwise operators except for actual Bit Manipulation.

I personally dislike Automatic semicolons, because they might lead to hard-to-find Bugs.

Collapse
 
elsyng profile image
Ellis

Many aspects of js might definitely lead to hard-to-find bugs.

Collapse
 
elsyng profile image
Ellis • Edited

Fun list, useful too.

I recognise two distinct groups, though:

  1. Actually quite well known features which many developers use on a daily basis now,
  2. Esoteric features which few developers do (or should) use.
Collapse
 
oculus42 profile image
Samuel Rouse

Thanks for the article! This is fun trip down memory lane of many old features now opposed strongly for daily use. You will see many of them in compiled production code, still.

18 and on are more like the new features that people should definitely know.

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

JavaScript allows for chained assignments, which can assign a single value to multiple variables in one statement

Assignment in JS is not a statement unless combined with var, let, or const.

We use the assignment operator (=) to perform the assignment, and that assignment has a value, which is the second operand of the assignment operator (the value being assigned to the variable).

It's not that JS 'allows for chained assignments', they are possible as a direct result of the fact that an assignment using the assignment operator has a value, i.e. a = 2 has a value of 2.

So, in your example:

let a, b, c;
a = b = c = 5;
Enter fullscreen mode Exit fullscreen mode

The code sets c to the value of 5, b to the value of c = 5 (which we know from the value of the assignment is also 5), and a to the value of b = c = 5 (which is also 5).

Collapse
 
warkentien2 profile image
Philip Warkentien II

Good list, there were a few things I wasn't aware of. That said: #9 and #17 are the same. #3 missed the opportunity of showing a tagged template literal being used, since the setup is just another function, might be glanced over.

Collapse
 
legolasdk profile image
simon

When would one ever use "2 -- comma operator" ?

Collapse
 
miketalbot profile image
Mike Talbot ⭐

Sometimes in for loops:

for (let i = 0, j = 10; i < j; i++, j--) {
  console.log(i, j);
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
legolasdk profile image
simon

I dont think that is the same. let x = (1, 2); console.log(x); would be using the mentioned feature. But this will just log ‘2’

Thread Thread
 
miketalbot profile image
Mike Talbot ⭐

It's the same feature, you're just not using the return value.

Collapse
 
jonrandy profile image
Jon Randy 🎖️

Code golf

Collapse
 
artydev profile image
artydev

Thank you :-)

Collapse
 
silverium profile image
Soldeplata Saketos

number #25 is simply a lie

Image description

Collapse
 
wldomiciano profile image
Wellington Domiciano • Edited

Is not a lie, it's a feature in DevTools 111!

To better facilitate debugging, DevTools now supports evaluating expressions with private class members.
Source: developer.chrome.com/blog/new-in-d...

Your code produces an error when used in a <script> tag.

To reproduce the error in DevTools, try this:

(() => {
  class Counter {
    #count = 0;
    increment() {
      this.#count++;
    }
    getCount() {
      return this.#count;
    }
  }

  const a = new Counter();

  console.log(a.#count);
})()
Enter fullscreen mode Exit fullscreen mode

Sample code

Collapse
 
silverium profile image
Soldeplata Saketos • Edited

ah, thanks for pointing that out. In any case I dislike very much classes, but I am glad they added the true privacy for properties.

I am more fan for functional programming, factories, pure functions, etc.

To create a private member which is not even visible:

(()=>{
const superPrivateCounter = 0;
  return {
   getCount: () => superPrivateCounter;
}
})()
Enter fullscreen mode Exit fullscreen mode
Collapse
 
wangliwen profile image
WangLiwen

Nice.

Collapse
 
kevinleebuchan profile image
KevinLeeBuchan • Edited

Number 3 has no example. I can't tell what you're trying to communicate.

Collapse
 
jerin_stephen profile image
Stephen BJ

awesome dude ,,,
more useful :P

Collapse
 
tzdesign profile image
Tobi

Holy Shot. I’m using comma in swift expressions since for ever and never new it’s possible in js. I will definitely use it now

Collapse
 
tzdesign profile image
Tobi

Unfortunately it’s not like I thought it works in conditions. The last one will be returned. No wonder I did not see it in the wild.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.