Top 5 JavaScript secrets
Tags: javascript, webdev
Published: 2020-09-03 20:34:43

JavaScript is a very...  **a very special language**. Even when you think you know all its secrets, it can still surprise you.

Like most things in this World, not all of JS' secrets are really useful. In fact most of them aren't, as everything not well-known by others only leads to  **confusion**. Using secret tips and tricks can make your code run faster or maybe even be smaller, but it'll certainly degrade its  **readability**, which is bad for all the potential reader of your code - including yourself from the future.

But, with this little warning out of the way, there's nothing wrong with knowing these secrets - either to be able to read other's cryptic code, or just to show off.

So, without further ado, let's explore 5 of what I think are some of the least-known  **JavaScript secrets**!

# Void operator

Did you know that there's a  `void`  operator in JS? What does it do you might ask? Well, it takes an expression (either simple or complex one wrapped in  `()`) you provide right after it, evaluates it, and...  **always returns**  `undefined`.

```javascript
void 0; // undefined
void "text"; // undefined
void {}; // undefined
void (() => {}); // undefined
// ... you get the point
```

So, what kind of use-case is there for such a  **mind-boggling operator**? Well, as it turns out - there's one. Believe it or not  `undefined`  can  **actually be defined**!

```javascript
(() => {
  const undefined = "foo";
  console.log(undefined, typeof undefined); // "foo", "string"
  console.log(void 0, typeof void 0); // undefined, "undefined"
})();
```

For your information, in JS,  `undefined`  isn't a  **reserved keyword**  and can be used as a variable name, effectively overriding the global in a certain scope.

Using the  `void`  operator with random expression (usually  `0`) assures you that you'll get the proper unchanged  `undefined`  no matter what.

# Optional parentheses

Parentheses are omnipresent in JavaScript - just as in almost any other programming language. But did you know that you don't have to always write them, even in places where you normally do?

## Class constructor

The safest place to omit parentheses is in a parameter-less  **class constructor**  call. That's right - you can just remove your parentheses, save those 2 bytes of space, and have your code working just fine!

```javascript
new Date();
new Date;
new Date().getYear();
(new Date).getYear(); // parentheses needed in a different place
```  

## IIFE

The second and last (from what I know) place where you can omit parentheses is in IIFEs or  **Immediately-Invoked Function Expressions**.

Typically, to use IIFE you need to wrap the function expression with parentheses and follow that with another pair of parentheses to actually call the function.

```javascript
(() => {
  // ...
})();
(function () {
  // ...
})();
```

But in reality, the wrapping parentheses aren't always required... at least under certain conditions. You can do so with function expressions defined with the  `function`  keyword and only when the IIFE result is being  **assigned to a variable**  or when it's preceded by  **an unary operator**  (like  `void`,  `!`, etc.).

```javascript
void function () {
  // ...
}();
const result = function () {
  // ...
}();
```

The operator or assignment is necessary so that the parser knows that the following function is actually a  **function expression**.

Sadly, this method doesn't work with arrow functions, so if your goal is just to shave off some bytes, I suggest you use the arrow and discussed parentheses after all.

# Comma operator

Next up we've got another operator - this time  **shorter**  and much more useful! It's a  **comma**  (`,`) - yeah, you've read that right - which in JS allows you to execute multiple expressions, one by one while  _"returning"_  the value retrieved from  **the last expression**. Take a look:

```javascript
// parentheses are required for proper assignment
const x = (1, 2, 3, 4); // 4
const y = ((() => "a")(), (() => "b")()); // "b"
const test = () => {
  return console.log(y), y;
};
test(); // logs "b" and returns "b"
```

So, as you can see, the possibilities of the comma operator are  **truly impressive**. You can use any expression and pretty much anything else with a little bit of help from the IIFEs. And when you combine that with  **arrow functions**  or  `console.log()`  for debugging you've got some impressively-short lambdas or better debugging experience without an additional line of code!

# In operator

And while we're in the topic of operators, why not discuss yet another under-appreciated constructs from this category - the  `in`  operator. The only use-case for this operator is to check whether an object  **contains certain property**, like so:

```javascript
const obj = { a: 1, b: 2, c: 3 };
"a" in obj; // true
"d" in obj; // false
delete obj.a;
obj.b = undefined;
"a" in obj; // false
"b" in obj; // true
```

So, why would you use a fancy operator, instead of simply checking for a property with an  `obj[prop]`  syntax like a normal person?

Well, there are some specific differences and thus  **advantages**  to this approach. First off, it's very convenient to use it for checking for the existence of properties that could hold  **falsy values**. In such cases,  `typeof obj[prop] === "undefined"`  would be required, which is certainly much more verbose than  `"prop" in obj`.

With that said, the drawback (or a feature depending on how you look at it) of the  `in`  operator is that it returns  `true`  even for properties that have been directly assigned the  `undefined`  value. If this is what you want, then I guess it's fine, but it also means that you'd have to use the  `delete`  operator to  **delete properties**, instead of simply assigning  `undefined`  (which is a bit slower).

# Labels

Lastly, we've got a feature that's also rarely used -  **labels**. In JS, labels (like  `name:`) can be used to effectively  **name blocks of code**  and different  **loop statements**  (e.g.  `for`). Having such names assigned to specific parts of your code allows you to later reference these parts for use with statements like  `continue`  and  `break`.

```javascript
outer: for (let i = 0; i < 10; i++) {
  inner: for (let j = 0; j < 10; j++) {
    if (i === j) {
      continue outer;
    }
    console.log(i, j);
  }
}

block: {
  // Yup, code blocks are a thing
  console.log("You'll see this");
  break block; // You can break form code blocks when they're labelled
  console.log("But not that");
}
```

Labels are especially useful when dealing with complex  **control flow**  within  **nested loops**. Sure, you can use them to `break` out of code blocks, but I really don't know why would you do that - just use a functions or even IIFEs like a normal person.

# Summary

So, that's my list of some of the most interesting and lesser-known JavaScript secrets.  **Let me know**  in the  **comments**  how many of these you did/didn't know about before reading this article. Oh, and also - if you like this kind of stuff, I highly encourage you to  **check out**  2 of mine web dev  [tricks](https://areknawo.com/7-adorable-web-development-tricks/)  [articles](https://areknawo.com/5-interesting-and-not-necessarily-useful-javascript-tricks/), and all the other stuff on this blog where I cover secrets of the  [Console API](https://areknawo.com/getting-creative-with-the-console-api/),  [Object API](https://areknawo.com/secrets-of-the-javascript-object-api/), and  [many](https://areknawo.com/exploring-the-hidden-potential-of-javascript-arrays/)  [more](https://areknawo.com/rocking-js-data-structures/)! Really cool stuff!

For more up-to-date web dev content,  **follow me**  on  [Twitter](https://twitter.com/areknawo),  [Facebook](https://facebook.com/areknawoblog), or through  [my personal blog](https://areknawo.com). Thanks for reading and happy coding!