9 Little Javascript Tricks

A computer and a phone on a desk

Updated on August 5, 2019 at 8:02 am by Mehmet Egemen Albayrak

I like to play with the code. When I see some way of writing code in somewhere for Javascript, I immediately try to understand inner-workings of it. In this post, I will show you 10 strange Javascript situations/tricks and explanations of them.

Python-like range() in Javascript

In Python, the range is used a lot in for loops. In Javascript people usually use for loop with index but you can have a better way of using forEach with something like the range in Python.

for index in range(7):
    print(index)

is something like this in Javascript

[...Array(7)].forEach((e, i) => {
  // e is undefined because array contains 7 undefineds
  // i is index
  console.log(i);
});

/**
 * Logs to the console:
 * 0
 * 1
 * 2
 * 3
 * 4
 * 5
 * 6
 */

Assertion

Assertion is important to increase the readability of the code. Even though it is not necessary for functions to check their input sometimes, putting assertion to tell other developers that what kind of input the function expects is a good way of programming.

function assert(condition) {
  if(!condition) throw new Error("Assertion Error");
}

assert(5 == true); // Throws Error: Assertion Error

Flat Array

Flatting an array with a reduce is a good way of understanding how reduce works.

// From Airbnb style guide

[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
  console.log(acc);
  const flatten = acc.concat(item);
  return flatten;
});

/**
 * Prints:
 * [0, 1]
 * [0, 1, 2, 3]
 * 
 * Returns:
 * [0, 1, 2, 3, 4, 5]
 */

I think reduce works in a little bit unpredictable way. When you provide an array of elements, it iterates over the elements. In the first loop, the first element of the array goes to acc, second goes to item. In our case in the first loop acc is [0, 1] and item is [2, 3]. After the first loop, there is a second loop comes with the item [4, 5], concatenating itself with the array [0, 1, 2, 3]. After two loops, the function ends.

There is also a contemporary way of doing it for any depth of nested arrays

// From MDN

let arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

let arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

let arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

Nested Reference

When we assign a variable to an object, this variable becomes a reference to the object. The same thing is not true for that object’s properties.

const obj = {
  aKey: "aValue",
  anotherKey: 1
}

let variable = obj.anotherKey;

console.log(variable)
variable += 1
console.log(variable)
console.log(obj.anotherKey)

/**
 * Prints:
 * 1
 * 2
 * 1
 */

In this example variable is not a reference to the object property, it copies the value.

Always Public

According to Airbnb standard using underscores before a variable is not good. But some software developers(maybe I should say engineers), including Martin Fowler, uses underscore before the variable in a class constructor to denote that that variable is private.

class Person {
  constructor(name) {
    this._name = name;
  }
  get name() {return this._name}
  set name(name) {this._name = name}
}

const john = new Person("John");

john._name = "Elias";

console.log(john.name);
console.log("--------------------");
console.log(john._name);

/**
 * Prints:
 * Elias
 * --------------------
 * Elias
 */

This practice doesn’t reflect reality. Variables in a constructor are always public, even though you put an underscore before them.

Map the Array from Object

Did you know that every array is actually an object? An array is an object whose keys are sequential numbers starting from 0 and has a numeric property with the key “length”. You can create an array from such an object and map it to a different array in one command.

const obj = {
  0: 1,
  1: 2,
  2: 3,
  length: 3
}

function double(aNumber) {
  return aNumber * 2;
}

console.log(Array.from(obj, double));

/**
 * Prints:
 * [2, 4, 6]
 */

No Set

You can’t set a variable in a constructor from inside or outside if you provide a getter but not a setter.

class SomeClass {
  constructor() {
    this._name = "Mehmet";
  }
  get name() { return this._name }
}

const mehmetObj = new SomeClass();

console.log(mehmetObj.name); // prints "Mehmet"
mehmetObj.name = "Egemen";
console.log(mehmetObj.name); // prints "Mehmet"

Best Way of Undefined

There are many ways of expressing an undefined value

let undefinedVariable;

if (undefinedVariable === undefined) 
  console.log(true);
if (typeof undefinedVariable === 'undefined') 
  console.log(true);
if (undefinedVariable === void 0) 
  console.log(true);

/** They all equal to undefined
 * undefined is actually a global property. (It's not a keyword).
 * So, undefined can be changed, whereas void is an operator, which 
 * cannot be overridden in javascript and always returns the value undefined.
 */

console.log(undefined); // Prints undefined
var undefined = 1;
console.log(undefined);
// It will print
// 1

Inline Factory

I call the following technique inline factory function and it shows the expressive power of Javascript

function returnClass() {
  return new class InlineClass {
    constructor() {
      this.longName = "some brazilian name with 12 words"
    }
  }()
}

const inlineClassObj = returnClass();
console.log(inlineClassObj.longName);
/**
 * Prints:
 * some brazilian name with 12 words
 */

I plan to continue this post as a series, hope you liked it. If you want to ask something or just say your good wishes, don’t forget to comment. You can share the post with others if you think they will benefit. Also, you can subscribe by clicking here for more well-thought and unique content. I wish you a good day.

Content Protection by DMCA.com
Javascript littletricks

Leave a Reply

Your email address will not be published. Required fields are marked *

Great! You want to be a part of our community.  With the form below, you can subscribe to quality content.