Understanding Logical Assignment Operators

·

6 min read

Understanding Logical Assignment Operators

In the realm of JavaScript, logical assignment operators offer a concise and powerful way to manipulate variables based on logical conditions. These operators combine the functionality of logical operators (such as && and ||) with the assignment operator (=) to perform conditional assignments in a single statement. In this article, we will explore the concept and usage of logical assignment operators in JavaScript, providing detailed explanations and practical examples. We will also talk about browser compatibility and some drawbacks (gotchas) you should consider when using logical assignment operators.

Introducing Logical Assignment Operators

Logical assignment operators are shorthand expressions that allow you to assign a value to a variable based on a logical condition. JavaScript provides three main logical assignment operators:

  • &&= (Logical AND assignment): Assigns the value on the right side to the variable on the left side if the variable is truthy.

  • ||= (Logical OR assignment): Assigns the value on the right side to the variable on the left side if the variable is falsy (e.g., undefined, null, false, 0, NaN).

  • ??= (Logical nullish assignment): Assigns the value on the right side to the variable on the left side if the variable is null or undefined.

Basic Examples

Let's start with some basic examples to illustrate the usage of logical assignment operators:

a. Logical AND assignment (&&=):

let a = 15;
a &&= 30; // If a is truthy, assign 30 to a
console.log(a); // Output: 30 (since a is truthy)

let b;
b &&= 40; // If b is truthy, assign 40 to b
console.log(b); // Output: undefined (since b is falsy)

b. Logical OR assignment (||=):

let a = 15;
a ||= 30; // If a is falsy, assign 30 to a
console.log(a); // Output: 15 (since a is truthy)

let b;
b &&= 40; // If b is falsy, assign 40 to b
console.log(b); // Output: 40 (since b is falsy)

c. Logical nullish assignment (??=):

let a = null;
a ??= 50; // If a is null or undefined, assign 50 to a
console.log(a); // Output: 50 (since a is null)

let b = 0;
b ??= 60; // If b is null or undefined, assign 60 to b
console.log(b); // Output: 0 (since b is falsy but not null or undefined)

One thing you should beware of is that logical assignment operators are short-circuited. This implies that the right-hand side is not evaluated if the left-hand side fails the condition.

Practical Use Cases

Now that we've talked about what logical assignments are, and their respective syntaxes, let's dive into some real-world scenarios in which they come in handy:

a. Logical AND assignment (&&=):

Personally, the first use case that comes to mind when talking about the logical AND assignment is conditionally overriding default values based on user settings.

const user = {
  name: 'John',
  age: 25,
  isAdmin: false,
};

// Update isAdmin property only if user is an admin
const isAdmin = true;
isAdmin &&= user.isAdmin;

console.log(isAdmin); // Output: false

In this example, the logical AND assignment operator is used to update the isAdmin variable if it has a truthy value. It evaluates and assigns the value of user.isAdmin only if isAdmin is true.

b. Logical OR assignment (||=):

One practical use of the logical OR assignment is that it can be very handy for setting default values of parameters:

function greet(name) {
  name ||= 'Anonymous'; // Assign 'Anonymous' if name is falsy
  console.log(`Hello, ${name}!`);
}

greet(); // Output: Hello, Anonymous!
greet('Saje'); // Output: Hello, Saje!

Another scenario in which I find this operator very useful is conditionally re-fetching data:

let config;

// fetching data from an API
async function fetchConfig() {
    const json = await fetch('example.com/api')
    const data = json.JSON()

    return data //return value from the fetch
}

config ||= fetchConfig() // trigger fetch if config is falsy

In the example above, we have a variable called config, and a function fetchConfig which fetches data from an API and returns the value. The logical assignment is then used to call the function if config has a falsy value. By doing this, we prevent the function from being called unnecessarily, since the right-hand side (fetchConfig) is only evaluated if the left-hand side (config) has a falsy value.

NOTE: in the example above, if the function also returns 0 as a value, you should use the Nullish Assignment Operator (??=) instead.

c. Logical nullish assignment (??=):

A really handy use case of the nullish assignment operator is for setting default values for user-defined variables:

const defaultConfig = {
  theme: 'light',
  fontSize: 14,
};

// Simulated user preferences
let userConfig = {
  fontSize: 16,
  colorScheme: 'dark',
};

// Apply default values only for nullish properties
userConfig.theme ??= defaultConfig.theme;
userConfig.fontSize ??= defaultConfig.fontSize;

In this example, the logical nullish assignment operator is used to apply default values from defaultConfig only to properties in userConfig that are null or undefined. It ensures that the default values are assigned only to properties that have not been explicitly set.

Advantages - Why Use Logical Assignments

If the examples and use cases above are not enough to convince you why you should switch to logical assignment operators, here are some advantages they provide:

  • Concise and Readable Code: Using logical assignment operators reduces the need for conditional statements or multiple lines of code, resulting in cleaner and more readable code.

  • Efficient Assignment: These operators provide a straightforward way to assign values based on logical conditions, promoting code efficiency and simplicity.

  • Default Value Assignment: Logical assignment operators can be useful when assigning default values to variables that may be falsy or nullish.

Gotchas to Consider Before Using Logical Assignment Operators

While logical assignment operators are very handy and can save you a lot of headaches, there are a few things you should consider before totally switching to logical operators:

  • Evaluation Order: The evaluation of logical assignment operators follows short-circuit evaluation. It means that the right-hand side of the assignment is evaluated only if the left-hand side expression is truthy. This can lead to unintended behavior if there are side effects or dependencies in the right-hand side expression that you were relying on.

  • Mutability and Side Effects: Be cautious when using logical assignment operators with mutable values or when there are side effects involved. These operators modify the original value in place, which can lead to unexpected behavior and make the code harder to reason about. Consider creating new variables or using immutable data structures when necessary.

  • Readability and Maintenance: While logical assignment operators can be concise, they can also make the code less readable, especially if used excessively or in complex expressions. Ensure to strike a balance between brevity and clarity.

  • Developer Familiarity: When working in a team, not all developers may be familiar with the logical assignment operators. Consider the level of familiarity and understanding among team members before extensively using these operators.

  • Implicit Type Conversion (Coercion): Logical assignment operators rely on type coercion to evaluate the operands. This can be tricky and even result in unexpected results/errors if you're not certain about the data type of the left-hand side of the operation.

Compatibility and Browser Support

Logical assignment operators were introduced in ECMAScript 2021 (ES12) and may not be supported in older browsers. Ensure that your target environment supports these operators or consider using transpilers or polyfills for backward compatibility.

Conclusion

Logical assignment operators in JavaScript empower developers to perform conditional assignments in a concise and elegant manner. Understanding how to use ||=, &&=, and ??= operators allows you to streamline your code, improve readability, and assign default values effectively. Leveraging these operators intelligently can enhance your productivity and contribute to writing more maintainable JavaScript code.

Did you find this article valuable?

Support Paul Saje by becoming a sponsor. Any amount is appreciated!