javascript shorthand

Don’t Miss These 25+ JavaScript Shorthand Techniques

JavaScript Shorthand Techniques: A Comprehensive Guide

As JavaScript continues to evolve, so does the elegance with which we can write it. One of the areas where this is evident is in its shorthand techniques, which not only make your code leaner but can also enhance performance. In this post, we’re diving deep into over 25 of these shorthand techniques to streamline your JavaScript journey.

If you have any question, feel free to contact us.

Conditional Shorthands

Conditionals are fundamental constructs in JavaScript, allowing for decision-making in code. Shorthand techniques can make these conditionals more concise without sacrificing clarity.

Ternary Operator

An alternative to the standard if-else construct that returns a value based on a condition.

				
					// Longhand
let result;
if (x > 10) {
    result = "greater";
} else {
    result = "lesser";
}


// Shorthand
const result = x > 10 ? "greater" : "lesser";

				
			
  • Use Cases: Useful for simple decisions within the code where a value is being assigned based on a condition.

  • Performance Considerations: Almost identical performance to if-else but provides cleaner syntax for simple decisions.

  • Compatibility Notes: Supported across all modern browsers.

Truthy and Falsy Checks

In JavaScript, values like 0, null, undefined, NaN, "" are “falsy”. All other values are “truthy”. This characteristic can be used to create shorthands.

				
					// Longhand
if (value !== null && value !== undefined && value !== "") {
    // Code
}


// Shorthand
if (value) {
    // Code
}

				
			
  • Use Cases: Checking the existence or validity of a variable before proceeding.

  • Performance Considerations: Slightly faster due to fewer checks, but be aware of JavaScript’s truthy and falsy values.

  • Compatibility Notes: Universally supported.

Short-Circuit Evaluation

Using logical OR || and logical AND && to return a value or execute a function if a certain condition is true.

				
					// Longhand
if (value) {
    executeFunction();
}


// Shorthand
value && executeFunction();

				
			
  • Use Cases: Quickly executing functions or assigning values based on conditions.

  • Performance Considerations: Similar performance but offers more concise syntax.

  • Compatibility Notes: Universally supported.

Nullish Coalescing Operator (??)

The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.

				
					// Longhand
let response;
if (data === null || data === undefined) {
    response = "Default";
} else {
    response = data;
}


// Shorthand
const response = data ?? "Default";

				
			
  • Use Cases: Setting a default value for variables that might be null or undefined.

  • Performance Considerations: Similar performance but offers more specific and concise syntax compared to ||.

  • Compatibility Notes: Supported in ES11 (ES2020) and above, might not be available in older browsers without a transpiler.

Optional Chaining (?.)

The optional chaining (?.) operator allows reading the value of a property within a chain of connected objects without having to check if each reference in the chain is valid.

				
					// Longhand
let value;
if (obj && obj.nestedObj && obj.nestedObj.property) {
    value = obj.nestedObj.property;
}


// Shorthand
const value = obj?.nestedObj?.property;

				
			
  • Use Cases: Safely accessing nested object properties without checking each level for existence.

  • Performance Considerations: Slightly faster in scenarios with deep nesting due to fewer checks.

  • Compatibility Notes: Supported in ES11 (ES2020) and above, might not be available in older browsers without a transpiler.

Logical Assignment Operators

Logical assignment operators combine logical operators (&&, ||, or ??) with assignment expressions.

				
					// Longhand
if (x) {
    x = y;
}


// Shorthand
x &&= y;

				
			
  • Use Cases: Assigning a value to a variable based on the variable’s current value.

  • Performance Considerations: Very similar performance, primarily a syntactic convenience.

  • Compatibility Notes: Supported in ES12 (ES2021) and above, might not be available in older browsers without a transpiler.

Multiple Conditions Check

For situations where a variable needs to be checked against multiple values.

				
					// Longhand
if (value === 1 || value === 2 || value === 3) {
    // Do something
}


// Shorthand
if ([1, 2, 3].includes(value)) {
    // Do something
}

				
			
  • Use Cases: Checking if a value exists in a predefined list of possibilities.

  • Performance Considerations: The shorthand may be slightly slower for very large arrays, but offers cleaner syntax.

  • Compatibility Notes: The includes method is supported in ES7 (ES2016) and above.

Using `in` for Property Checking

Instead of using typeof or chaining properties to check if an object contains a certain property, you can use the in operator.

				
					// Longhand
if (obj && "property" in obj) {
    // Do something
}


// Shorthand
if ("property" in obj) {
    // Do something
}

				
			
  • Use Cases: Checking if an object has a specific property without worrying about prototype chain.

  • Performance Considerations: The in operator is efficient and concise, especially when not sure if the object itself is defined.

  • Compatibility Notes: Widely supported across JavaScript versions.

Switch Case with Object Literals

Instead of using a switch statement, you can employ an object literal to map cases to their respective functions, making the code more concise and readable.

				
					// Longhand
switch (key) {
    case 'a':
        doSomethingA();
        break;
    case 'b':
        doSomethingB();
        break;
    default:
        doDefault();
}


// Shorthand
const actions = {
    'a': doSomethingA,
    'b': doSomethingB,
    'default': doDefault
};

(actions[key] || actions['default'])();

				
			
  • Use Cases: When needing to map keys to specific actions, especially when there are many potential actions.

  • Performance Considerations: Object lookup is typically faster than a switch statement, especially for a large number of cases.

  • Compatibility Notes: Works in all modern JavaScript versions.

Array to Boolean Conversion

In scenarios where you need to check if an array is empty or not, you can leverage JavaScript’s type coercion.

				
					// Longhand
if (arr.length > 0) {
    // Array is not empty
}


// Shorthand
if (arr.length) {
    // Array is not empty
}

				
			
  • Use Cases: Quickly checking if an array (or string) is empty.

  • Performance Considerations: Both methods are efficient, but the shorthand offers more concise syntax.

  • Compatibility Notes: Universally supported in JavaScript.

Loop Shorthands

`for...of` Loop (for Arrays)

The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, array-like objects, TypedArray, Map, Set, and user-defined iterables.

				
					// Longhand
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}


// Shorthand
for (const value of arr) {
    console.log(value);
}

				
			
  • Use Cases: When you want to iterate over values of an iterable, especially when you don’t need access to the index.

  • Performance Considerations: Generally similar performance to traditional for loops for arrays.

  • Compatibility Notes: Supported in ES6 and above.

`for...in` Loop (for Objects)

The for...in statement iterates over all enumerable properties of an object, in an arbitrary order.

				
					// Longhand
for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(key, obj[key]);
    }
}


// Shorthand
for (const key in obj) {
    console.log(key, obj[key]);
}

				
			
  • Use Cases: When you want to iterate over properties of an object.

  • Performance Considerations: It’s efficient for objects, but not recommended for arrays.

  • Compatibility Notes: Supported in all versions of JavaScript.

Array `forEach` Method

The forEach() method executes a provided function once for each array element.

				
					// Longhand
for (let i = 0; i < arr.length; i++) {
    doSomething(arr[i]);
}


// Shorthand
arr.forEach(item => doSomething(item));

				
			
  • Use Cases: When you want a concise way to iterate over array elements without needing the index.

  • Performance Considerations: Slightly slower than a traditional for loop but often more readable.

  • Compatibility Notes: Supported in ES5 and above.

`map`, `filter`, and `reduce`

These are powerful array methods that can often replace traditional loops, especially when transforming arrays.

				
					// Using map to double each item
const doubled = arr.map(item => item * 2);

// Using filter to select even items
const evens = arr.filter(item => item % 2 === 0);

// Using reduce to sum all items
const sum = arr.reduce((acc, item) => acc + item, 0);

				
			
  • Use Cases:

    • map: When transforming each item in an array.
    • filter: When selecting a subset of items based on a criterion.
    • reduce: When accumulating a single value from an array.
  • Performance Considerations: These methods are often more readable than traditional loops, but there might be a slight performance overhead for very large arrays.

  • Compatibility Notes: Supported in ES5 and above.

Array `every` and `some` Methods

These methods are used to test array elements against a condition.

				
					const numbers = [10, 20, 30, 40, 50];

// Check if all numbers are greater than 5
const allGreaterThanFive = numbers.every(num => num > 5); // true

// Check if any number is less than 25
const anyLessThanTwentyFive = numbers.some(num => num < 25); // false

				
			
  • Use Cases:

    • every: To check if all elements of an array satisfy a condition.
    • some: To check if at least one element of an array satisfies a condition.
  • Performance Considerations: More efficient than traditional loops for these specific checks as they stop iterating once the condition is found false (for every) or true (for some).

  • Compatibility Notes: Supported in ES5 and above.

`Array.from` with `map` Function

The Array.from() method creates a new, shallow-copied instance of an array. When combined with a map function, it can replace loops for creating arrays based on other data structures or ranges.

				
					// Create an array of squares from 0 to 4
const squares = Array.from({ length: 5 }, (_, i) => i * i); // [0, 1, 4, 9, 16]

				
			
  • Use Cases:

    • Transforming array-like structures (like NodeList) into arrays.
    • Creating arrays from iterables.
  • Performance Considerations: Efficient and often more readable for transforming data structures into arrays.

  • Compatibility Notes: Supported in ES6 and above.

Using the Spread Operator to Convert Array-like Structures

The spread operator (...) can be used to convert array-like structures (e.g., NodeList, arguments object) into arrays.

				
					// Converting NodeList to Array
const nodes = document.querySelectorAll('div');
const nodesArray = [...nodes];

// Converting arguments object to array
function logArgs() {
  const args = [...arguments];
  console.log(args);
}

				
			
  • Use Cases:

    • Transforming DOM node collections into arrays.
    • Converting the arguments object into an array inside functions.
  • Performance Considerations: Generally efficient, especially for smaller collections.

  • Compatibility Notes: The spread operator is supported in ES6 and above.

Recursive `for...of` for Nested Arrays

JavaScript’s for...of loop can be used recursively to handle arrays within arrays, commonly known as “nested arrays.”

				
					function recursiveForOf(arr) {
  for (const item of arr) {
    if (Array.isArray(item)) {
      recursiveForOf(item);
    } else {
      console.log(item);
    }
  }
}

const nestedArray = [1, [2, 3], [4, [5, 6]]];
recursiveForOf(nestedArray); // Logs 1, 2, 3, 4, 5, 6

				
			
  • Use Cases:

    • Flattening nested arrays.
    • Iterating through multi-level data structures.
  • Performance Considerations: Recursion can be memory-intensive for deeply nested arrays. Always be cautious of potential stack overflow errors.

  • Compatibility Notes: for...of is supported in ES6 and above.

`Array.reduce()` for Transformations

The Array.reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.

				
					const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // Outputs: 10

				
			
  • Use Cases:

    • Summation of array values.
    • Transforming arrays into other data structures.
  • Performance Considerations: Highly efficient for transforming data in a single pass.

  • Compatibility Notes: Supported in ES5 and above.

`Array.flatMap()` for Mapping and Flattening

Array.flatMap() is similar to Array.map(), but it first maps each element using a mapping function, then flattens the result into a new array.

				
					const arr = [1, 2, 3, 4];
const result = arr.flatMap(x => [x, x * 2]);
console.log(result); // Outputs: [1, 2, 2, 4, 3, 6, 4, 8]

				
			
  • Use Cases:

    • When you want to map and then flatten results into a new array.
  • Performance Considerations: Efficient for combined mapping and flattening operations.

  • Compatibility Notes: Supported in ES2019 and above.

Function Shorthands

Arrow Functions

Arrow functions allow for a shorter syntax when writing functions in JavaScript. They are particularly useful for small, single-purpose functions.

				
					// Longhand
function add(x, y) {
  return x + y;
}


// Shorthand
const add = (x, y) => x + y;

				
			
  • Use Cases:

    • Callbacks in higher-order functions.
    • Event handlers.
    • Single-expression functions.
  • Performance Considerations: Similar performance to traditional functions.

  • Compatibility Notes: Supported in ES6 and above.

Default Parameters

Default parameters allow you to set default values for your function parameters. This is useful when an argument isn’t provided.

				
					// Longhand
function greet(name) {
  if(name === undefined) {
    name = "Guest";
  }
  return "Hello, " + name;
}


// Shorthand
const greet = (name = "Guest") => "Hello, " + name;

				
			
  • Use Cases:

    • Setting default values for function arguments.
    • Avoiding checks for undefined or missing arguments.
  • Performance Considerations: No significant difference in performance.

  • Compatibility Notes: Supported in ES6 and above.

Implicit Return

For arrow functions with a single expression in the body, you can omit the return keyword and the curly braces.

				
					// Longhand
const double = (x) => {
  return x * 2;
}


// Shorthand
const double = x => x * 2;

				
			
  • Use Cases:

    • Small utility functions.
    • Callbacks with a single operation.
  • Performance Considerations: No significant difference in performance.

  • Compatibility Notes: Supported in ES6 and above.

Function Name Property

Functions in JavaScript have a name property that returns the name of the function.

				
					function greet() {}
console.log(greet.name); // Outputs: "greet"


// For anonymous functions, the `name` property is an empty string:
let greet = function() {}
console.log(greet.name); // Outputs: ""


// However, when assigned to a variable, the variable `name` is adopted:
let greetFunc = function greet() {}
console.log(greetFunc.name); // Outputs: "greet"

				
			
  • Use Cases:

    • Debugging: Helps identify functions in stack traces.
    • Function introspection.
  • Performance Considerations: Minimal overhead.

  • Compatibility Notes: Supported in ES6 and above.

Named Parameters with Destructuring

Using object destructuring to simulate named parameters in functions.

				
					// Longhand
function userInfo(user) {
  const name = user.name;
  const age = user.age;
  //...
}


// Shorthand
const userInfo = ({name, age}) => {
  //...
};

				
			
  • Use Cases:

    • When functions have many parameters, making them hard to manage.
    • Improving function call clarity.
  • Performance Considerations: Minimal overhead introduced due to destructuring.

  • Compatibility Notes: Supported in ES6 and above.

Share this
Send this to a friend