Nerd For Tech
Published in

Nerd For Tech

Quickie Dev #1: About falsy and default values in Javascript

Because setting default values in Javascript can seem very simple… until you realize you can’t actually override them!

When you write code, you want your variables to have clearly defined values, you want to know what they are equal to at any given point in your program. The easy case is when you explicitly set a variable: if you say that a = 2, then the value of a is 2 (obviously). But what about variables you haven't explicitly set? (Or haven't explicitly set yet?) Those variables still have their default value.

The problem

There are various ways of initializing a variable and plenty of articles on the net to give you some shorthands. In Javascript, a well-known technique is to use the logical “or” operator, ||, to override the default value when you initialize a variable. This is particularly neat when you have some default configuration and you want to override it with user-specific options.

For example, let’s say I’m writing a program to display geometric shapes. The idea is to show a square, a triangle and a circle on a row, either black or red, that are evenly spaced out. I have two settings I can tweak: the spacing between the shapes and a useBlack flag to tell whether to draw black or red shapes.

We can set the spacing between the shapes and the color used to draw them (black or red).

Now, most of the time, I want the shapes to be black and the spacing to be of 10 pixels. In order words, I can define my basic configuration as:

var config = {
spacing: 10, // in pixels
useBlack: true
}

And in my program, I’ll just use this configuration when calling my drawing logic:

var config = {
spacing: 10, // in pixels
useBlack: true
}

function run() {
const spacing = config.spacing;
const useBlack = config.useBlack;
// the magic functions that draw my shapes
setShapesSpacing(spacing);
setPaintColor(useBlack);
drawShapes();
}

run();

This works great! Now it’s time to add my user-custom variables: this time I want to draw shapes with a 2 pixels-spacing, so that they’re closer together. To do this, let’s create a second object to hold our user configuration and use the famous || operator that allows you to easily assign a value to a variable from a list of possible sources.

function run(options) {
const spacing = options.spacing || config.spacing;
const useBlack = options.useBlack || config.useBlack;
...
}
run({ spacing: 2 });

As you can see, you write the default value on the far right and then the possible override on the right, and we separate the two with the || operator. So you need to read this from right to left to get the real re-assignment order.

When I run this code, shapes are indeed closer together, yay!

Problem: However, if I decide to set a 0 pixel-spacing, then shapes suddenly jump back to their original position. Similarly, if I try and use the same technique for my colors by adding a useBlack set to false, nothing changes!

The why

This is because the || operator is actually returning the “first non-falsy operant”, or in other words the first value in your series of possibilities that is not considered “false” by Javascript. And there actually are more falsy values than we might think...!

When you pass in “0” or “false” as I just did, then this value is actually a falsy, so our initial base-configuration default will naturally pop up and our user-custom config will be ignored.

Note: as a rule-of-thumb, you can remember that using a falsy value with the || operator never returns the falsy value, and using a falsy value with the && operator always returns it.

Some solutions

To fix our problem, we have several possibilities.

Object.assign()

This allows you to completely overwrite the key-value pairs of an object. You start from a source and you “add on” one or more targets that may or may not share the same keys as the source:

const result = Object.assign(targetC, targetB, targetA, source);

Every time the same key is encountered, the program will simply overwrite the value. Else if there is a new key, it will be added to the final object with its new value. If none of the targets contain a key that is present in the source, then this key-value pair will be left unchanged.

Similarly to our previous example with the || operator, when using Object.assign you need to read the overwrites from right to left:

Using the ?? nullish coalescing operator (ECMA 2020)

Warning: this operator is only available if you are using Javascript ECMA 2020 or later.

The big difference between the ?? and the || operator is that the ?? operator only ignores the left operant if its is equal to null or undefined, instead of any falsy value. So a user-custom value of 0, an empty string or even NaN will not be skipped with this operator:

const spacing = options.spacing ?? 10;
// -> if options.spacing = 2, spacing = 2
// -> if options.spacing = 0, spacing = 0
// -> if options.spacing = null, spacing = 10

Reverting to a basic condition

If you’re unsure of your data or you’re afraid it might do something unexpected, you can always revert to an explicit condition (either with an if/else statement or with a ternary condition):

let spacing = 10;
if (typeof options.spacing === 'number') {
spacing = options.spacing;
}
let useBlack = options.useBlack === false ? false : true;

Note: be careful, you might be tempted to use !options.useBlack… but this will lead to the exact same issue as with the || operator since the ! operator checks for falsy values too.

To conclude

Javascript is famous for being a somewhat “implicit” language that often does quite weird things until you understand the underlying reasons. Since JS is not a typed language, using the logical or coalescing operators properly to set default values requires you to really know your data, the types of your variables and the values they can take. Still, when used correctly, they are both very powerful tools.

If you liked this article, you can find more blog posts about tech, AI and programming on my website :)

--

--

--

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

Recommended from Medium

Memory Foam Mattresses A Customers Overview https://t.co/vjsAXBDEIS

Challenges in Building for Fluency

All I want to do is initialise an array!

Web Dev Streaks Day- 45 (Milestone 7: Browser & Debug

Improving error handling in React Apollo

Hacking LinkedIn search results with a Chrome Extension — Milestone #1

jasonparseronline

Takeaways on Building a React Based App with Electron

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mina Pêcheux

Mina Pêcheux

I’m a freelance full-stack web & game developer. I’m passionate about topics like CGI, music, data science and more! Find me at: https://minapecheux.com :)

More from Medium

Console.log tricks : How to style a log

What’s a Framework or library in Javascript?

Framework and Libraries in Javascript by 404answernotfound

How to fix blurry elements that have “position: fixed”

A speeding train blurred by its motion

How To Generate an Alphabet JavaScript Array