Null Coalescing Operator in JavaScript with ECMAScript 2020

javascript conditional assignment undefined

  • Introduction

When working in a request-response lifecycle , you want to make sure that a response with the wanted body - or at least an informative response arrives so the client that requested the data stays in the loop. In case of null values , you'll probably want to return a different result.

JavaScript made sure this can be handled with its nullish operator also known as the Null Coalescing Operator , which was added to the language with ECMAScript 2020 . With it, you can either return a value or assign it to some other value, depending on a boolean expression.

This can be used to return default values if another value is missing, or to return different values based on any other boolean expression.

The Null Coalescing Operator belongs to the group of short-circuiting logical operators , which we'll take a look at in a moment.

It's somewhat similar to the Conditional Operator , which is sometimes known as the Ternary Operator :

In this guide, we'll be taking a look at the nullish/Null Coalescing Operator, short-circuiting and truthy and falsy values - through practical examples.
  • What is short-circuiting?

JavaScript evaluates operators from left to right. With exclusive operators where we need both values to evaluate to true, it's sometimes enough to check just the first evaluation statement.

If the left side of the operator is false , regardless of the right side, the operator results in false , so there's no point in evaluating the other side, and it's skipped to preserve computational power.

This process is called short-circuiting .

Before ES2020, JavaScript only had two short-circuit logical operators:

  • Logical operator AND - &&
  • Logical operator OR - ||

With the new update, JavaScript introduced another one:

  • Null Coalescing operator - ??

Short-circuiting itself makes code more efficient because less evaluations need to happen, though, via the Null Coalescing operator, we can also alter the code logic based on a short-circuiting operation.

For instance:

This code will result in:

Though, we could also ditch the if statement fully and use a short-circuit AND operator instead to shorten the statements:

(x+y) > 20 evaluates to true so the next block is entered, and the message is printed.

Where is short-circuiting here?

If the (x+y) > 20 was falsy (we'll talk about this in a second), the JavaScript interpreter wouldn't even look at the second part of the expression, and the block would never run.

Similarly enough, we can use the logical OR operator in a similar way:

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Naturally, this results in:

These examples are pretty simple, yet logical operators can solve a lot of practical problems and make your code a lot cleaner. However, if not used properly, you might cause yourself a headache.

  • Truthy and Falsy values

When working with logical operators, you'll come around the terms truthy value and falsy value .

A truthy value is any value that isn't:

  • '' - empty string
  • NaN - Not a Number

All these values are considered falsy .

In JavaScript, all the falsy values are evaluated as false when used in loops or if statements and all the truthy values are evaluated as true .

Now that we've got the prerequisites covered, let's finally take a look at the Nullish Operator .

  • Nullish Coalescing Operator

The Nullish Operator checks whether the value is nullish , not falsy . A nullish value is undefined or null .

This allows us to assign default non-null values to variables when we're unsure of the results.

For instance, let's mock a user service that retrieves a user from a database and returns their name. There's a 10% chance that the user doesn't exist, which is regulated by a Math.random() call. In 10 calls to the database, we're likely to see at least one missing user - denoted by a null result:

The code will output either the name or a message denoting the lack of the user's existence in the database, though this requires us to perform null-checks in the if statement.

This results in:

By happenstance, this seems to be an odd run - 3 null results! This code works just fine, and handles null cases if the database returns a null value.

Alternatively, we could've used something much more concise:

Using a conditional operator , we've returned either null or John Doe with their respective ID. If Math.random() > 0.9 , null is returned, so there's a 10% probability it'll be returned on each call to the database.

Then, assuming possible null values - we've used the Nullish Operator to assign a new value to the user result if it turns out to be null . If db.find() returns null , the right-hand value kicks in and is returned instead.

This code is much cleaner and shorter than the if-else statements, and if-else statements have a higher tendency to cascade and get even more complex. Though, chaining multiple short-circuiting operators gets hard to read as well, so it's not really advisable to replace all if-else blocks:

Do you know what this would print? Considering random possibilities, it'd likely take you a while to parse this manually and see which values you can anticipate. This code has a tendency to result in 1 with null and 4 in some cases, as the returned default value for the nullish operator in this case is another null . Typically, you won't use more than one, or two, operators in cases like these.

To wrap this up, the sole purpose of the nullish operator is to allow you to always return some kind of default value, instead of returning something that doesn't exist - which, in JavaScript, is what null and undefined mean.

You might also like...

  • JavaScript: Check if First Letter of a String is Upper Case
  • Using Mocks for Testing in JavaScript with Sinon.js
  • For-each Over an Array in JavaScript
  • Commenting Code in JavaScript - Types and Best Practices

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

In this article

javascript conditional assignment undefined

React State Management with Redux and Redux-Toolkit

Coordinating state and keeping components in sync can be tricky. If components rely on the same data but do not communicate with each other when...

David Landup

Getting Started with AWS in Node.js

Build the foundation you'll need to provision, deploy, and run Node.js applications in the AWS cloud. Learn Lambda, EC2, S3, SQS, and more!

© 2013- 2024 Stack Abuse. All rights reserved.

Home

7 Tips to Handle undefined in JavaScript

Because JavaScript is permissive, developers have the temptation to access uninitialized values. I'm guilty of such bad practice too.

Often such risky actions generate undefined related errors:

  • TypeError: 'undefined' is not a function
  • TypeError: Cannot read property '<prop-name>' of undefined
  • and alike type errors .

JavaScript developers can understand the irony of this joke:

To reduce such errors, you have to understand the cases when undefined is generated. Let's explore undefined and its effect on code safety.

Table of Contents

1. what is undefined, 2. scenarios that create undefined, 3. undefined in arrays, 4. undefined and null differences, 5. conclusion.

JavaScript has 6 primitive types:

  • Boolean: true or false
  • Number: 1 , 6.7 , 0xFF
  • String: "Gorilla and banana"
  • Symbol: Symbol("name") (starting ES2015)
  • Undefined: undefined .

And a separated object type: {name: "Dmitri"} , ["apple", "orange"] .

From 6 primitive types undefined is a special value with its own type Undefined. According to ECMAScript specification :

Undefined value primitive value is used when a variable has not been assigned a value.

The standard clearly defines that you will receive undefined when accessing uninitialized variables, non-existing object properties, non-existing array elements, and alike.

A few examples:

The above example demonstrates that accessing:

  • an uninitialized variable number
  • a non-existing object property movie.year
  • or a non-existing array element movies[3]

are evaluated as undefined .

The ECMAScript specification defines the type of undefined value:

Undefined type is a type whose sole value is the undefined value.

In this sense, typeof operator returns 'undefined' string for an undefined value:

Of course typeof works nicely to verify whether a variable contains an undefined value:

2.1 Uninitialized variable

A declared variable but not yet assigned with a value ( uninitialized ) is undefined .

Plain and simple:

myVariable is declared and not yet assigned with a value. Accessing the variable evaluates to undefined .

An efficient approach to solve the troubles of uninitialized variables is whenever possible to assign an initial value . The less the variable exists in an uninitialized state, the better.

Ideally, you would assign a value right away after declaration const myVariable = 'Initial value' . But that's not always possible.

Tip 1: Favor const , otherwise use let , but say goodbye to var

const and let are block scoped (contrary to older function scoped var ) and exist in a temporal dead zone until the declaration line.

If you want to define a variable, always start with const , which creates an immutable binding .

One of the nice features of const is that you must assign an initial value to the variable const myVariable = 'initial' . The variable is not exposed to the uninitialized state and accessing undefined is impossible.

Let's check the function that verifies whether a word is a palindrome:

length and half variables are assigned with a value once. It seems reasonable to declare them as const since these variables aren't going to change.

Use let declaration for variables whose value can change. Whenever possible assign an initial value right away, e.g. let index = 0 .

What about the old-school var ? My suggestion is to stop using it .

var declaration problem is the variable hoisting within the function scope. You can declare a var variable somewhere at the end of the function scope, but still, you can access it before declaration: and you'll get an undefined .

myVariable is accessible and contains undefined even before the declaration line: var myVariable = 'Initial value' .

Contrary, a const or let variable cannot be accessed before the declaration line — the variable is in a temporal dead zone before the declaration. And that's nice because you have less chance to access an undefined .

The above example updated with let (instead of var ) throws a ReferenceError because the variable in the temporal dead zone is not accessible.

Encouraging the usage of const for immutable bindings or let otherwise ensures a practice that reduces the appearance of the uninitialized variable.

Tip 2: Increase cohesion

Cohesion characterizes the degree to which the elements of a module (namespace, class, method, block of code) belong together. The cohesion can be high or low .

A high cohesion module is preferable because the elements of such a module focus solely on a single task. It makes the module:

  • Focused and understandable : easier to understand what the module does
  • Maintainable and easier to refactor : the change in the module affects fewer modules
  • Reusable : being focused on a single task, makes the module easier to reuse
  • Testable : it's easier to test a module that's focused on a single task

High cohesion accompanied by loose coupling is the characteristic of a well-designed system.

A code block can be considered a small module. To profit from the benefits of high cohesion, keep the variables as close as possible to the code block that uses them.

For instance, if a variable solely exists to form the logic of block scope, then declare and make the variable exist only within that block (using const or let declarations). Do not expose this variable to the outer block scope, since the outer block shouldn't need this variable.

One classic example of the unnecessarily extended life of variables is the usage of for cycle inside a function:

index , item , and length variables are declared at the beginning of the function body. However, they are used only near the end. What's the problem with this approach?

Between the declaration at the top and the usage in for statement the variables index and item are uninitialized and exposed to undefined . They have an unreasonably long lifecycle in the entire function scope.

A better approach is to move these variables as close as possible to their usage place:

index and item variables exist only in the block scope of for statement. They don't have any meaning outside of for . length variable is declared close to the source of its usage too.

The refactored code is better because:

  • The variables are not exposed to an uninitialized state, thus you have no risk of accessing undefined
  • Moving the variables as close as possible to their usage place increases the code readability
  • High cohesive chunks of code are easier to refactor and extract into separate functions, if necessary

2.2 Accessing a non-existing property

When accessing a non-existing object property , JavaScript returns undefined .

Let's demonstrate that in an example:

favoriteMovie is an object with a single property title . Accessing a non-existing property actors using a property accessor favoriteMovie.actors evaluates to undefined .

Accessing a non-existing property does not throw an error. The problem appears when trying to get data from the non-existing property (e.g. favoriteMovie.actors.length ) — the most common undefined issue.

"TypeError: Cannot read property <prop> of undefined" is a very common error message generated by accessing data from non-existing properties.

Let's slightly modify the previous code snippet to illustrate a TypeError throw:

favoriteMovie does not have the property actors , so favoriteMovie.actors evaluates to undefined .

As a result, accessing the length of an undefined value using the expression favoriteMovie.actors.length throws a TypeError .

A good way to bypass this problem is to restrict the object to have always defined the properties that it holds.

Unfortunately, often you don't have control over the objects. Such objects may have a different set of properties in diverse scenarios. So you have to handle all these scenarios manually.

Let's implement a function append(array, toAppend) that adds at the beginning and/or at the end of an array new elements. toAppend parameter accepts an object with properties:

  • first : element inserted at the beginning of array
  • last : element inserted at the end of array .

The function returns a new array instance, without altering the original array.

The first version of append() , a bit naive, may look like this:

Because toAppend object can omit first or last properties, it is obligatory to verify whether these properties exist in toAppend .

A property accessor evaluates to undefined if the property does not exist. The first temptation to check whether first or last properties are present is to verify them against undefined . This is performed in conditionals if(toAppend.first){} and if(toAppend.last){} ...

Not so fast. This approach has a drawback. undefined , as well as false , null , 0 , NaN , and '' are falsy values.

In the current implementation of append() , the function doesn't allow to insert falsy elements:

0 and false are falsy. Because if(toAppend.first){} and if(toAppend.last){} actually compare against falsy, these elements are not inserted into the array. The function returns the initial array [10] without modifications, instead of the expected [0, 10, false] .

The tips that follow explain how to correctly check the property's existence.

Tip 3: Check the property existence

Fortunately, JavaScript offers a bunch of ways to determine if the object has a specific property:

  • obj.prop !== undefined : compare against undefined directly
  • typeof obj.prop !== 'undefined' : verify the property value type
  • obj.hasOwnProperty('prop') : verify whether the object has its own property
  • 'prop' in obj : verify whether the object has an own or inherited property

My recommendation is to use in operator. It has a short and readable syntax. in operator presence suggests a clear intent of checking whether an object has a specific property, without accessing the actual property value.

obj.hasOwnProperty('prop') is a nice solution too. It's slightly longer than in operator and verifies only the object's own properties.

Let's improve append(array, toAppend) function using in operator:

in operator fixes the problem by inserting falsy elements 0 and false . Now, adding these elements at the beginning and the end of [10] produces the expected result [0, 10, false] .

Tip 4: Destructuring to access object properties

When accessing an object property, sometimes it's necessary to set a default value if the property does not exist.

You might use in accompanied with a ternary operator to accomplish this:

Ternary operator syntax becomes daunting when the number of properties to check increases. For each property, you have to create a new line of code to handle the defaults, increasing an ugly wall of similar-looking ternary operators.

To use a more elegant approach, let's get familiar with a great ES2015 feature called object destructuring .

Object destructuring allows inline extraction of object properties directly into variables and sets a default value if the property does not exist. A convenient syntax to avoid dealing directly with undefined .

Indeed, the property extraction is better:

To see things in action, let's define a useful function that wraps a string in quotes.

quote(subject, config) accepts the first argument as the string to be wrapped. The second argument config is an object with the properties:

  • char : the quote char, e.g. ' (single quote) or " (double quote). Defaults to " .
  • skipIfQuoted : the boolean value to skip quoting if the string is already quoted. Defaults to true .

Applying the benefits of object destructuring, let's implement quote() :

const { char = '"', skipIfQuoted = true } = config destructuring assignment in one line extracts the properties char and skipIfQuoted from config object.

If some properties are missing in the config object, the destructuring assignment sets the default values: '"' for char and false for skipIfQuoted .

Fortunately, the function still has room for improvement.

Let's move the destructuring assignment into the parameters section. And set a default value (an empty object { } ) for the config parameter, to skip the second argument when default settings are enough.

The destructuring assignment replaces the config parameter in the function's signature. I like that: quote() becomes one line shorter.

= {} on the right side of the destructuring assignment ensures that an empty object is used if the second argument is not indicated during the call: quote('Sunny day') .

Object destructuring is a powerful feature that handles efficiently the extraction of properties from objects. I like the possibility to specify a default value to be returned when the accessed property doesn't exist. As a result, you avoid undefined and the hassle around it.

Tip 5: Fill the object with default properties

If there is no need to create variables for every property, as the destructuring assignment does, the object that misses some properties can be filled with default values.

Object.assign(target, source1, source2, ...) copies the values of all enumerable own properties from one or more source objects into the target object. The function returns the target object.

For instance, you need to access the properties of unsafeOptions object that doesn't always contain its full set of properties.

To avoid undefined when accessing a non-existing property from unsafeOptions , let's make some adjustments:

  • Define an object defaults that holds the default property values
  • Call Object.assign({ }, defaults, unsafeOptions) to build a new object options . The new object receives all properties from unsafeOptions , but the missing ones are taken from defaults .

unsafeOptions contains only fontSize property. defaults object defines the default values for properties fontSize and color .

Object.assign() takes the first argument as a target object {} . The target object receives the value of fontSize property from unsafeOptions source object. And the value of color property from defaults source object, because unsafeOptions doesn't contain color .

The order in which the source objects are enumerated does matter: later source object properties overwrite earlier ones.

You are now safe to access any property of options object, including options.color that wasn't available in unsafeOptions initially.

Fortunately, an easier alternative to fill the object with default properties exists. I recommend using the spread properties in object initializers .

Instead of Object.assign() , use the object spread syntax to copy into the target object all own and enumerable properties from source objects:

The object initializer spreads properties from defaults and unsafeOptions source objects. The order in which the source objects are specified is important: later source object properties overwrite earlier ones.

Filling an incomplete object with default property values is an efficient strategy to make your code safe and durable. No matter the situation, the object always contains the full set of properties: and undefined cannot be generated.

Bonus tip: nullish coalescing

The operator nullish coalescing evaluates to a default value when its operand is undefined or null :

Nullish coalescing operator is convenient to access an object property while having a default value when this property is undefined or null :

styles object doesn't have the property color , thus styles.color property accessor is undefined . styles.color ?? 'black' evaluates to the default value 'black' .

styles.fontSize is 18 , so the nullish coalescing operator evaluates to the property value 18 .

2.3 Function parameters

The function parameters implicitly default to undefined .

Usually, a function defined with a specific number of parameters should be invoked with the same number of arguments. That's when the parameters get the values you expect:

When calling multiply(5, 3) , the parameters a and b receive 5 and respectively 3 values. The multiplication is calculated as expected: 5 * 3 = 15 .

What does happen when you omit an argument on invocation? The corresponding parameter inside the function becomes undefined .

Let's slightly modify the previous example by calling the function with just one argument:

The invocation multiply(5) is performed with a single argument: as a result a parameter is 5 , but the b parameter is undefined .

Tip 6: Use default parameter value

Sometimes a function does not require the full set of arguments on invocation. You can set defaults for parameters that don't have a value.

Recalling the previous example, let's make an improvement. If b parameter is undefined , let default it to 2 :

The function is invoked with a single argument multiply(5) . Initially, a parameter is 2 and b is undefined .

The conditional statement verifies whether b is undefined . If it happens, b = 2 assignment sets a default value.

While the provided way to assign default values works, I don't recommend comparing directly against undefined . It's verbose and looks like a hack.

A better approach is to use the ES2015 default parameters feature. It's short, expressive, and has no direct comparisons with undefined .

Adding a default value to parameter b = 2 looks better:

b = 2 in the function signature makes sure that if b is undefined , the parameter defaults to 2 .

The default parameters feature is intuitive and expressive. Always use it to set default values for optional parameters.

2.4 Function return value

Implicitly, without return statement, a JavaScript function returns undefined .

A function that doesn't have return statement implicitly returns undefined :

square() function does not return any computation results. The function invocation result is undefined .

The same situation happens when return statement is present, but without an expression nearby:

return; statement is executed, but it doesn't return any expression. The invocation result is also undefined .

Of course, indicating near return the expression to be returned works as expected:

Now the function invocation is evaluated to 4 , which is 2 squared.

Tip 7: Don't trust the automatic semicolon insertion

The following list of statements in JavaScript must end with semicolons ( ; ):

  • empty statement
  • let , const , var , import , export declarations
  • expression statement
  • debugger statement
  • continue statement, break statement
  • throw statement
  • return statement

If you use one of the above statements, be sure to indicate a semicolon at the end:

At the end of both let declaration and return statement an obligatory semicolon is written.

What happens when you don't want to indicate these semicolons? In such a situation ECMAScript provides an Automatic Semicolon Insertion (ASI) mechanism, which inserts for you the missing semicolons.

Helped by ASI, you can remove the semicolons from the previous example:

The above text is a valid JavaScript code. The missing semicolons are automatically inserted for you.

At first sight, it looks pretty promising. ASI mechanism lets you skip the unnecessary semicolons. You can make the JavaScript code smaller and easier to read.

There is one small, but annoying trap created by ASI. When a newline stands between return and the returned expression return \n expression , ASI automatically inserts a semicolon before the newline return; \n expression .

What does it mean to have return; statement inside of a function? The function returns undefined . If you don't know in detail the mechanism of ASI, the unexpectedly returned undefined is misleading.

For instance, let's study the returned value of getPrimeNumbers() invocation:

Between return statement and the array literal expression exists a new line. JavaScript automatically inserts a semicolon after return , interpreting the code as follows:

The statement return; makes the function getPrimeNumbers() return undefined instead of the expected array.

The problem is solved by removing the newline between return and array literal:

My recommendation is to study how exactly Automatic Semicolon Insertion works to avoid such situations.

Of course, never put a newline between return and the returned expression.

2.5 void operator

void <expression> evaluates the expression and returns undefined no matter the result of the evaluation.

One use case of void operator is to suppress expression evaluation to undefined , relying on some side-effect of the evaluation.

You get undefined when accessing an array element with an out-of-bounds index.

colors array has 3 elements, thus valid indexes are 0 , 1 , and 2 .

Because there are no array elements at indexes 5 and -1 , the accessors colors[5] and colors[-1] are undefined .

In JavaScript, you might encounter so-called sparse arrays . These are arrays that have gaps, i.e. at some indexes no elements are defined.

When a gap (aka empty slot) is accessed inside a sparse array, you also get an undefined .

The following example generates sparse arrays and tries to access their empty slots:

sparse1 is created by invoking an Array constructor with a numeric first argument. It has 3 empty slots.

sparse2 is created with an array literal with the missing second element.

In any of these sparse arrays accessing an empty slot evaluates to undefined .

When working with arrays, to avoid undefined , be sure to use valid array indexes and prevent the creation of sparse arrays.

What is the main difference between undefined and null ? Both special values imply an empty state.

undefined represents the value of a variable that hasn't been yet initialized , while null represents an intentional absence of an object .

Let's explore the difference in some examples.

The variable number is defined, however, is not assigned with an initial value:

number variable is undefined , which indicates an uninitialized variable.

The same uninitialized concept happens when a non-existing object property is accessed:

Because lastName property does not exist in obj , JavaScript evaluates obj.lastName to undefined .

On the other side, you know that a variable expects an object. But for some reason, you can't instantiate the object. In such case null is a meaningful indicator of a missing object .

For example, clone() is a function that clones a plain JavaScript object. The function is expected to return an object:

However clone() might be invoked with a non-object argument: 15 or null . The function cannot create a clone from these values, so it returns null — the indicator of a missing object.

typeof operator makes the distinction between undefined and null :

Also the strict quality operator === correctly differentiates undefined from null :

undefined existence is a consequence of JavaScript's permissive nature that allows the usage of:

  • uninitialized variables
  • non-existing object properties or methods
  • out-of-bounds indexes to access array elements
  • the invocation result of a function that returns nothing

Comparing directly against undefined is unsafe because you rely on a permitted but discouraged practice mentioned above.

An efficient strategy is to reduce the appearance of undefined keyword in your code by applying good habits such as:

  • reduce the usage of uninitialized variables
  • make the variables' lifecycle short and close to the source of their usage
  • whenever possible assign initial values to variables
  • favor const , otherwise use let
  • use default values for insignificant function parameters
  • verify the properties' existence or fill the unsafe objects with default properties
  • avoid the usage of sparse arrays

Is it good or bad that JavaScript has undefined and null to represent empty values?

Like the post? Please share!

Dmitri Pavlutin

Description

Specifications, browser compatibility.

The conditional (ternary) operator is the only JavaScript operator that takes three operands. This operator is frequently used as a shortcut for the if statement.

The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

Besides false , possible falsy expressions are:  null ,  NaN ,  0 , the empty string ( "" ), and  undefined . If condition  is any of these, the result of the conditional expression will be exprIfFalse .

A simple example:

One common usage is to handle a value that may be null :

Conditional chains

The ternary operator is right-associative, which means it can be "chained" in the following way, similar to an  if … else if … else if … else  chain:

  • if statement

Document Tags and Contributors

  • Conditional
  • JavaScript basics
  • JavaScript first steps
  • JavaScript building blocks
  • Introducing JavaScript objects
  • Introduction
  • Grammar and types
  • Control flow and error handling
  • Loops and iteration
  • Expressions and operators
  • Numbers and dates
  • Text formatting
  • Regular expressions
  • Indexed collections
  • Keyed collections
  • Working with objects
  • Details of the object model
  • Using promises
  • Iterators and generators
  • Meta programming
  • JavaScript modules
  • Client-side web APIs
  • A re-introduction to JavaScript
  • JavaScript data structures
  • Equality comparisons and sameness
  • Inheritance and the prototype chain
  • Strict mode
  • JavaScript typed arrays
  • Memory Management
  • Concurrency model and Event Loop
  • References:
  • ArrayBuffer
  • AsyncFunction
  • Float32Array
  • Float64Array
  • GeneratorFunction
  • InternalError
  • Intl.Collator
  • Intl.DateTimeFormat
  • Intl.ListFormat
  • Intl.Locale
  • Intl.NumberFormat
  • Intl.PluralRules
  • Intl.RelativeTimeFormat
  • ReferenceError
  • SharedArrayBuffer
  • SyntaxError
  • Uint16Array
  • Uint32Array
  • Uint8ClampedArray
  • WebAssembly
  • decodeURI()
  • decodeURIComponent()
  • encodeURI()
  • encodeURIComponent()
  • parseFloat()
  • Arithmetic operators
  • Array comprehensions
  • Assignment operators
  • Bitwise operators
  • Comma operator
  • Comparison operators
  • Destructuring assignment
  • Expression closures
  • Generator comprehensions
  • Grouping operator
  • Legacy generator function expression
  • Logical operators
  • Object initializer
  • Operator precedence
  • (currently at stage 1) pipes the value of an expression into a function. This allows the creation of chained function calls in a readable manner. The result is syntactic sugar in which a function call with a single argument can be written like this:">Pipeline operator
  • Property accessors
  • Spread syntax
  • async function expression
  • class expression
  • delete operator
  • function expression
  • function* expression
  • in operator
  • new operator
  • void operator
  • Legacy generator function
  • async function
  • for await...of
  • for each...in
  • function declaration
  • import.meta
  • try...catch
  • Arrow functions
  • Default parameters
  • Method definitions
  • Rest parameters
  • The arguments object
  • constructor
  • element loaded from a different domain for which you violated the same-origin policy.">Error: Permission denied to access property "x"
  • InternalError: too much recursion
  • RangeError: argument is not a valid code point
  • RangeError: invalid array length
  • RangeError: invalid date
  • RangeError: precision is out of range
  • RangeError: radix must be an integer
  • RangeError: repeat count must be less than infinity
  • RangeError: repeat count must be non-negative
  • ReferenceError: "x" is not defined
  • ReferenceError: assignment to undeclared variable "x"
  • ReferenceError: can't access lexical declaration`X' before initialization
  • ReferenceError: deprecated caller or arguments usage
  • ReferenceError: invalid assignment left-hand side
  • ReferenceError: reference to undefined property "x"
  • SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
  • SyntaxError: "use strict" not allowed in function with non-simple parameters
  • SyntaxError: "x" is a reserved identifier
  • SyntaxError: JSON.parse: bad parsing
  • SyntaxError: Malformed formal parameter
  • SyntaxError: Unexpected token
  • SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
  • SyntaxError: a declaration in the head of a for-of loop can't have an initializer
  • SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
  • SyntaxError: for-in loop head declarations may not have initializers
  • SyntaxError: function statement requires a name
  • SyntaxError: identifier starts immediately after numeric literal
  • SyntaxError: illegal character
  • SyntaxError: invalid regular expression flag "x"
  • SyntaxError: missing ) after argument list
  • SyntaxError: missing ) after condition
  • SyntaxError: missing : after property id
  • SyntaxError: missing ; before statement
  • SyntaxError: missing = in const declaration
  • SyntaxError: missing ] after element list
  • SyntaxError: missing formal parameter
  • SyntaxError: missing name after . operator
  • SyntaxError: missing variable name
  • SyntaxError: missing } after function body
  • SyntaxError: missing } after property list
  • SyntaxError: redeclaration of formal parameter "x"
  • SyntaxError: return not in function
  • SyntaxError: test for equality (==) mistyped as assignment (=)?
  • SyntaxError: unterminated string literal
  • TypeError: "x" has no properties
  • TypeError: "x" is (not) "y"
  • TypeError: "x" is not a constructor
  • TypeError: "x" is not a function
  • TypeError: "x" is not a non-null object
  • TypeError: "x" is read-only
  • TypeError: 'x' is not iterable
  • TypeError: More arguments needed
  • TypeError: Reduce of empty array with no initial value
  • TypeError: can't access dead object
  • TypeError: can't access property "x" of "y"
  • TypeError: can't assign to property "x" on "y": not an object
  • TypeError: can't define property "x": "obj" is not extensible
  • TypeError: can't delete non-configurable array element
  • TypeError: can't redefine non-configurable property "x"
  • TypeError: cannot use 'in' operator to search for 'x' in 'y'
  • TypeError: cyclic object value
  • TypeError: invalid 'instanceof' operand 'x'
  • TypeError: invalid Array.prototype.sort argument
  • TypeError: invalid arguments
  • TypeError: invalid assignment to const "x"
  • TypeError: property "x" is non-configurable and can't be deleted
  • TypeError: setting getter-only property "x"
  • TypeError: variable "x" redeclares argument
  • URIError: malformed URI sequence
  • Warning: -file- is being assigned a //# sourceMappingURL, but already has one
  • Warning: 08/09 is not a legal ECMA-262 octal constant
  • Warning: Date.prototype.toLocaleFormat is deprecated
  • Warning: JavaScript 1.6's for-each-in loops are deprecated
  • Warning: String.x is deprecated; use String.prototype.x instead
  • Warning: expression closures are deprecated
  • Warning: unreachable code after return statement
  • X.prototype.y called on incompatible type
  • JavaScript technologies overview
  • Lexical grammar
  • Enumerability and ownership of properties
  • Iteration protocols
  • Transitioning to strict mode
  • Template literals
  • Deprecated features
  • ECMAScript 2015 support in Mozilla
  • ECMAScript 5 support in Mozilla
  • Firefox JavaScript changelog
  • New in JavaScript 1.1
  • New in JavaScript 1.2
  • New in JavaScript 1.3
  • New in JavaScript 1.4
  • New in JavaScript 1.5
  • New in JavaScript 1.6
  • New in JavaScript 1.7
  • New in JavaScript 1.8
  • New in JavaScript 1.8.1
  • New in JavaScript 1.8.5
  • Documentation:
  • All pages index
  • Methods index
  • Properties index
  • Pages tagged "JavaScript"
  • JavaScript doc status
  • The MDN project

Learn the best of web development

Get the latest and greatest from MDN delivered straight to your inbox.

Thanks! Please check your inbox to confirm your subscription.

If you haven’t previously confirmed a subscription to a Mozilla-related newsletter you may have to do so. Please check your inbox or your spam filter for an email from us.

JavaScript Check if Undefined – How to Test for Undefined in JS

Joel Olawanle

An undefined variable or anything without a value will always return "undefined" in JavaScript. This is not the same as null, despite the fact that both imply an empty state.

You'll typically assign a value to a variable after you declare it, but this is not always the case.

When a variable is declared or initialized but no value is assigned to it, JavaScript automatically displays "undefined". It looks like this:

Also, when you try accessing values in, for example, an array or object that doesn’t exist, it will throw undefined .

Here's another example:

In this article, you will learn the various methods and approaches you can use to know if a variable is undefined in JavaScript. This is necessary if you want to avoid your code throwing errors when performing an operation with an undefined variable.

In case you are in a rush, here are the three standard methods that can help you check if a variable is undefined in JavaScript:

Let’s now explain each of these methods in more detail.

How to Check if a Variable is Undefined in JavaScript with Direct Comparison

One of the first methods that comes to mind is direct comparison. This is where you compare the output to see if it returns undefined . You can easily do this in the following way:

This also works for arrays as you can see below:

And it definitely also works for other variables:

How to Check if a Variable is Undefined in JavaScript with typeof

We can also use the type of the variable to check if it’s undefined . Luckily for us undefined is a datatype for an undefined value as you can see below: ‌

With this we can now use the datatype to check undefined for all types of data as we saw above. Here is what the check will look like for all three scenarios we have considered:

Optional chaining '?.'

The optional chaining ?. is a safe way to access nested object properties, even if an intermediate property doesn’t exist.

The “non-existing property” problem

If you’ve just started to read the tutorial and learn JavaScript, maybe the problem hasn’t touched you yet, but it’s quite common.

As an example, let’s say we have user objects that hold the information about our users.

Most of our users have addresses in user.address property, with the street user.address.street , but some did not provide them.

In such case, when we attempt to get user.address.street , and the user happens to be without an address, we get an error:

That’s the expected result. JavaScript works like this. As user.address is undefined , an attempt to get user.address.street fails with an error.

In many practical cases we’d prefer to get undefined instead of an error here (meaning “no street”).

…and another example. In Web development, we can get an object that corresponds to a web page element using a special method call, such as document.querySelector('.elem') , and it returns null when there’s no such element.

Once again, if the element doesn’t exist, we’ll get an error accessing .innerHTML property of null . And in some cases, when the absence of the element is normal, we’d like to avoid the error and just accept html = null as the result.

How can we do this?

The obvious solution would be to check the value using if or the conditional operator ? , before accessing its property, like this:

It works, there’s no error… But it’s quite inelegant. As you can see, the "user.address" appears twice in the code.

Here’s how the same would look for document.querySelector :

We can see that the element search document.querySelector('.elem') is actually called twice here. Not good.

For more deeply nested properties, it becomes even uglier, as more repetitions are required.

E.g. let’s get user.address.street.name in a similar fashion.

That’s just awful, one may even have problems understanding such code.

There’s a little better way to write it, using the && operator:

AND’ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but also isn’t ideal.

As you can see, property names are still duplicated in the code. E.g. in the code above, user.address appears three times.

That’s why the optional chaining ?. was added to the language. To solve this problem once and for all!

Optional chaining

The optional chaining ?. stops the evaluation if the value before ?. is undefined or null and returns undefined .

Further in this article, for brevity, we’ll be saying that something “exists” if it’s not null and not undefined .

In other words, value?.prop :

  • works as value.prop , if value exists,
  • otherwise (when value is undefined/null ) it returns undefined .

Here’s the safe way to access user.address.street using ?. :

The code is short and clean, there’s no duplication at all.

Here’s an example with document.querySelector :

Reading the address with user?.address works even if user object doesn’t exist:

Please note: the ?. syntax makes optional the value before it, but not any further.

E.g. in user?.address.street.name the ?. allows user to safely be null/undefined (and returns undefined in that case), but that’s only for user . Further properties are accessed in a regular way. If we want some of them to be optional, then we’ll need to replace more . with ?. .

We should use ?. only where it’s ok that something doesn’t exist.

For example, if according to our code logic user object must exist, but address is optional, then we should write user.address?.street , but not user?.address?.street .

Then, if user happens to be undefined, we’ll see a programming error about it and fix it. Otherwise, if we overuse ?. , coding errors can be silenced where not appropriate, and become more difficult to debug.

If there’s no variable user at all, then user?.anything triggers an error:

The variable must be declared (e.g. let/const/var user or as a function parameter). The optional chaining works only for declared variables.

Short-circuiting

As it was said before, the ?. immediately stops (“short-circuits”) the evaluation if the left part doesn’t exist.

So, if there are any further function calls or operations to the right of ?. , they won’t be made.

For instance:

Other variants: ?.(), ?.[]

The optional chaining ?. is not an operator, but a special syntax construct, that also works with functions and square brackets.

For example, ?.() is used to call a function that may not exist.

In the code below, some of our users have admin method, and some don’t:

Here, in both lines we first use the dot ( userAdmin.admin ) to get admin property, because we assume that the user object exists, so it’s safe read from it.

Then ?.() checks the left part: if the admin function exists, then it runs (that’s so for userAdmin ). Otherwise (for userGuest ) the evaluation stops without errors.

The ?.[] syntax also works, if we’d like to use brackets [] to access properties instead of dot . . Similar to previous cases, it allows to safely read a property from an object that may not exist.

Also we can use ?. with delete :

The optional chaining ?. has no use on the left side of an assignment.

For example:

The optional chaining ?. syntax has three forms:

  • obj?.prop – returns obj.prop if obj exists, otherwise undefined .
  • obj?.[prop] – returns obj[prop] if obj exists, otherwise undefined .
  • obj.method?.() – calls obj.method() if obj.method exists, otherwise returns undefined .

As we can see, all of them are straightforward and simple to use. The ?. checks the left part for null/undefined and allows the evaluation to proceed if it’s not so.

A chain of ?. allows to safely access nested properties.

Still, we should apply ?. carefully, only where it’s acceptable, according to our code logic, that the left part doesn’t exist. So that it won’t hide programming errors from us, if they occur.

  • If you have suggestions what to improve - please submit a GitHub issue or a pull request instead of commenting.
  • If you can't understand something in the article – please elaborate.
  • To insert few words of code, use the <code> tag, for several lines – wrap them in <pre> tag, for more than 10 lines – use a sandbox ( plnkr , jsbin , codepen …)

Lesson navigation

  • © 2007—2024  Ilya Kantor
  • about the project
  • terms of usage
  • privacy policy
  • Skip to main content
  • Select language
  • Skip to search
  • Destructuring assignment

Unpacking values from a regular expression match

Es2015 version, invalid javascript identifier as a property name.

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

Description

The object and array literal expressions provide an easy way to create ad hoc packages of data.

The destructuring assignment uses similar syntax, but on the left-hand side of the assignment to define what values to unpack from the sourced variable.

This capability is similar to features present in languages such as Perl and Python.

Array destructuring

Basic variable assignment, assignment separate from declaration.

A variable can be assigned its value via destructuring separate from the variable's declaration.

Default values

A variable can be assigned a default, in the case that the value unpacked from the array is undefined .

Swapping variables

Two variables values can be swapped in one destructuring expression.

Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the XOR-swap trick ).

Parsing an array returned from a function

It's always been possible to return an array from a function. Destructuring can make working with an array return value more concise.

In this example, f() returns the values [1, 2] as its output, which can be parsed in a single line with destructuring.

Ignoring some returned values

You can ignore return values that you're not interested in:

You can also ignore all returned values:

Assigning the rest of an array to a variable

When destructuring an array, you can unpack and assign the remaining part of it to a variable using the rest pattern:

Note that a SyntaxError will be thrown if a trailing comma is used on the left-hand side with a rest element:

When the regular expression exec() method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to unpack the parts out of this array easily, ignoring the full match if it is not needed.

Object destructuring

Basic assignment, assignment without declaration.

A variable can be assigned its value with destructuring separate from its declaration.

The ( .. ) around the assignment statement is required syntax when using object literal destructuring assignment without a declaration.

{a, b} = {a: 1, b: 2} is not valid stand-alone syntax, as the {a, b} on the left-hand side is considered a block and not an object literal.

However, ({a, b} = {a: 1, b: 2}) is valid, as is var {a, b} = {a: 1, b: 2}

NOTE: Your ( ..) expression needs to be preceded by a semicolon or it may be used to execute a function on the previous line.

Assigning to new variable names

A property can be unpacked from an object and assigned to a variable with a different name than the object property.

A variable can be assigned a default, in the case that the value unpacked from the object is undefined .

Setting a function parameter's default value

Es5 version, nested object and array destructuring, for of iteration and destructuring, unpacking fields from objects passed as function parameter.

This unpacks the id , displayName and firstName from the user object and prints them.

Computed object property names and destructuring

Computed property names, like on object literals , can be used with destructuring.

Rest in Object Destructuring

The Rest/Spread Properties for ECMAScript proposal (stage 3) adds the rest syntax to destructuring. Rest properties collect the remaining own enumerable property keys that are not already picked off by the destructuring pattern.

Destructuring can be used with property names that are not valid JavaScript identifiers  by providing an alternative identifer that is valid.

Specifications

Browser compatibility.

[1] Requires "Enable experimental Javascript features" to be enabled under `about:flags`

Firefox-specific notes

  • Firefox provided a non-standard language extension in JS1.7 for destructuring. This extension has been removed in Gecko 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37). See bug 1083498 .
  • Starting with Gecko 41 (Firefox 41 / Thunderbird 41 / SeaMonkey 2.38) and to comply with the ES2015 specification, parenthesized destructuring patterns, like ([a, b]) = [1, 2] or ({a, b}) = { a: 1, b: 2 } , are now considered invalid and will throw a SyntaxError . See Jeff Walden's blog post and bug 1146136 for more details.
  • Assignment operators
  • "ES6 in Depth: Destructuring" on hacks.mozilla.org

Document Tags and Contributors

  • Destructuring
  • ECMAScript 2015
  • JavaScript basics
  • JavaScript first steps
  • JavaScript building blocks
  • Introducing JavaScript objects
  • Introduction
  • Grammar and types
  • Control flow and error handling
  • Loops and iteration
  • Expressions and operators
  • Numbers and dates
  • Text formatting
  • Regular expressions
  • Indexed collections
  • Keyed collections
  • Working with objects
  • Details of the object model
  • Iterators and generators
  • Meta programming
  • A re-introduction to JavaScript
  • JavaScript data structures
  • Equality comparisons and sameness
  • Inheritance and the prototype chain
  • Strict mode
  • JavaScript typed arrays
  • Memory Management
  • Concurrency model and Event Loop
  • References:
  • ArrayBuffer
  • AsyncFunction
  • Float32Array
  • Float64Array
  • GeneratorFunction
  • InternalError
  • Intl.Collator
  • Intl.DateTimeFormat
  • Intl.NumberFormat
  • ParallelArray
  • ReferenceError
  • SIMD.Bool16x8
  • SIMD.Bool32x4
  • SIMD.Bool64x2
  • SIMD.Bool8x16
  • SIMD.Float32x4
  • SIMD.Float64x2
  • SIMD.Int16x8
  • SIMD.Int32x4
  • SIMD.Int8x16
  • SIMD.Uint16x8
  • SIMD.Uint32x4
  • SIMD.Uint8x16
  • SharedArrayBuffer
  • StopIteration
  • SyntaxError
  • Uint16Array
  • Uint32Array
  • Uint8ClampedArray
  • WebAssembly
  • decodeURI()
  • decodeURIComponent()
  • encodeURI()
  • encodeURIComponent()
  • parseFloat()
  • Arithmetic operators
  • Array comprehensions
  • Bitwise operators
  • Comma operator
  • Comparison operators
  • Conditional (ternary) Operator
  • Expression closures
  • Generator comprehensions
  • Grouping operator
  • Legacy generator function expression
  • Logical Operators
  • Object initializer
  • Operator precedence
  • Property accessors
  • Spread syntax
  • async function expression
  • class expression
  • delete operator
  • function expression
  • function* expression
  • in operator
  • new operator
  • void operator
  • Legacy generator function
  • async function
  • for each...in
  • function declaration
  • try...catch
  • Arguments object
  • Arrow functions
  • Default parameters
  • Method definitions
  • Rest parameters
  • constructor
  • element loaded from a different domain for which you violated the same-origin policy.">Error: Permission denied to access property "x"
  • InternalError: too much recursion
  • RangeError: argument is not a valid code point
  • RangeError: invalid array length
  • RangeError: invalid date
  • RangeError: precision is out of range
  • RangeError: radix must be an integer
  • RangeError: repeat count must be less than infinity
  • RangeError: repeat count must be non-negative
  • ReferenceError: "x" is not defined
  • ReferenceError: assignment to undeclared variable "x"
  • ReferenceError: deprecated caller or arguments usage
  • ReferenceError: invalid assignment left-hand side
  • ReferenceError: reference to undefined property "x"
  • SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
  • SyntaxError: "use strict" not allowed in function with non-simple parameters
  • SyntaxError: "x" is a reserved identifier
  • SyntaxError: JSON.parse: bad parsing
  • SyntaxError: Malformed formal parameter
  • SyntaxError: Unexpected token
  • SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
  • SyntaxError: a declaration in the head of a for-of loop can't have an initializer
  • SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
  • SyntaxError: for-in loop head declarations may not have initializers
  • SyntaxError: function statement requires a name
  • SyntaxError: identifier starts immediately after numeric literal
  • SyntaxError: illegal character
  • SyntaxError: invalid regular expression flag "x"
  • SyntaxError: missing ) after argument list
  • SyntaxError: missing ) after condition
  • SyntaxError: missing : after property id
  • SyntaxError: missing ; before statement
  • SyntaxError: missing = in const declaration
  • SyntaxError: missing ] after element list
  • SyntaxError: missing formal parameter
  • SyntaxError: missing name after . operator
  • SyntaxError: missing variable name
  • SyntaxError: missing } after function body
  • SyntaxError: missing } after property list
  • SyntaxError: redeclaration of formal parameter "x"
  • SyntaxError: return not in function
  • SyntaxError: test for equality (==) mistyped as assignment (=)?
  • SyntaxError: unterminated string literal
  • TypeError: "x" has no properties
  • TypeError: "x" is (not) "y"
  • TypeError: "x" is not a constructor
  • TypeError: "x" is not a function
  • TypeError: "x" is not a non-null object
  • TypeError: "x" is read-only
  • TypeError: More arguments needed
  • TypeError: can't access dead object
  • TypeError: can't define property "x": "obj" is not extensible
  • TypeError: can't delete non-configurable array element
  • TypeError: can't redefine non-configurable property "x"
  • TypeError: cyclic object value
  • TypeError: invalid 'in' operand "x"
  • TypeError: invalid Array.prototype.sort argument
  • TypeError: invalid arguments
  • TypeError: invalid assignment to const "x"
  • TypeError: property "x" is non-configurable and can't be deleted
  • TypeError: setting getter-only property "x"
  • TypeError: variable "x" redeclares argument
  • URIError: malformed URI sequence
  • Warning: -file- is being assigned a //# sourceMappingURL, but already has one
  • Warning: 08/09 is not a legal ECMA-262 octal constant
  • Warning: Date.prototype.toLocaleFormat is deprecated
  • Warning: JavaScript 1.6's for-each-in loops are deprecated
  • Warning: String.x is deprecated; use String.prototype.x instead
  • Warning: expression closures are deprecated
  • Warning: unreachable code after return statement
  • JavaScript technologies overview
  • Lexical grammar
  • Enumerability and ownership of properties
  • Iteration protocols
  • Transitioning to strict mode
  • Template literals
  • Deprecated features
  • ECMAScript 2015 support in Mozilla
  • ECMAScript 5 support in Mozilla
  • ECMAScript Next support in Mozilla
  • Firefox JavaScript changelog
  • New in JavaScript 1.1
  • New in JavaScript 1.2
  • New in JavaScript 1.3
  • New in JavaScript 1.4
  • New in JavaScript 1.5
  • New in JavaScript 1.6
  • New in JavaScript 1.7
  • New in JavaScript 1.8
  • New in JavaScript 1.8.1
  • New in JavaScript 1.8.5
  • Documentation:
  • All pages index
  • Methods index
  • Properties index
  • Pages tagged "JavaScript"
  • JavaScript doc status
  • The MDN project

IMAGES

  1. JavaScript undefined

    javascript conditional assignment undefined

  2. Conditional Statements in JavaScript

    javascript conditional assignment undefined

  3. Types of Conditional Statements in JavaScript with Example

    javascript conditional assignment undefined

  4. JavaScript if, else, and else if Conditional Statements

    javascript conditional assignment undefined

  5. Basic Javascript Tutorial

    javascript conditional assignment undefined

  6. What is a Conditional Statement in JavaScript or a Desicion Statement?

    javascript conditional assignment undefined

VIDEO

  1. Use Destructuring Assignment to Pass an Object as a Function's Parameters (ES6) freeCodeCamp

  2. Basic JavaScript Declare JavaScript Variables freeCodeCamp

  3. Lecture 1 of JS (Introduction of JS, variables, and datatypes)

  4. Programs of javascript using conditional statements

  5. JavaScript conditional statement 21-05-2023

  6. JavaScript Conditional Statement if,else and else if✅

COMMENTS

  1. Best Way for Conditional Variable Assignment

    There are two methods I know of that you can declare a variable's value by conditions. Method 1: If the condition evaluates to true, the value on the left side of the column would be assigned to the variable. If the condition evaluates to false the condition on the right will be assigned to the variable. You can also nest many conditions into ...

  2. JavaScript || or operator with an undefined variable

    @bryan: There's no need to assign false to v.If you simply do var v;, it will automatically have an initial value of undefined, so if v gets some other non-falsey value, x will be assigned that value. But if v isn't assigned anything, or gets another falsey value, x will get 10.Keep in mind that 0 is falsey. You should only use the "logical OR" in this manner if you're absolutely certain that ...

  3. Nullish coalescing operator (??)

    The nullish coalescing operator can be seen as a special case of the logical OR ( ||) operator. The latter returns the right-hand side operand if the left operand is any falsy value, not only null or undefined. In other words, if you use || to provide some default value to another variable foo, you may encounter unexpected behaviors if you ...

  4. Logical OR assignment (||=)

    Description. Logical OR assignment short-circuits, meaning that x ||= y is equivalent to x || (x = y), except that the expression x is only evaluated once. No assignment is performed if the left-hand side is not falsy, due to short-circuiting of the logical OR operator. For example, the following does not throw an error, despite x being const: js.

  5. Making decisions in your code

    We wanted to make a special mention of testing boolean (true/false) values, and a common pattern you'll come across again and again.Any value that is not false, undefined, null, 0, NaN, or an empty string ('') actually returns true when tested as a conditional statement, therefore you can simply use a variable name on its own to test whether it is true, or even that it exists (i.e. it is not ...

  6. Null Coalescing Operator in JavaScript with ECMAScript 2020

    Using a conditional operator, we've returned either null or John Doe with their respective ID. If Math.random() > 0.9, null is returned, so there's a 10% probability it'll be returned on each call to the database. Then, assuming possible null values - we've used the Nullish Operator to assign a new value to the user result if it turns out to be ...

  7. if...else

    Any value that is not undefined, null, 0, NaN, ... Note that there is no elseif syntax in JavaScript. However, you can write it with a space ... Assignment within the conditional expression. It is advisable to not use simple assignments in a conditional expression, because the assignment can be confused with equality when glancing over the code

  8. 7 Tips to Handle undefined in JavaScript

    Initially, a parameter is 2 and b is undefined. The conditional statement verifies whether b is undefined. If it happens, b = 2 assignment sets a default value. While the provided way to assign default values works, I don't recommend comparing directly against undefined. It's verbose and looks like a hack.

  9. Conditional (ternary) operator

    The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark (?), then an expression to execute if the condition is truthy followed by a colon (:), and finally the expression to execute if the condition is falsy. This operator is frequently used as an alternative to an if ...

  10. Conditional (ternary) operator

    An expression which is executed if the condition is falsy (that is, has a value which can be converted to false). Description. Besides false, possible falsy expressions are: null, NaN, 0, the empty string (""), and undefined. If condition is any of these, the result of the conditional expression will be exprIfFalse. A simple example:

  11. Conditional (ternary) Operator

    The conditional (ternary) operator is the only JavaScript operator that takes three operands. This operator is frequently used as a shortcut for the if statement. Syntax condition? expr1: expr2 Parameters condition (or conditions) An expression that evaluates to true or false. expr1, expr2 Expressions with values of any type. Description

  12. javascript

    This answer is dated - the null safe operators were officially added to ES6 ~10 months ago, and most browsers supported it for ~a year before it was official. @ArtOfWarfare They were not added to ES6 (ES2015) but to ES2020, so the answer is still factually correct and answering the question, which asked about ES6 only.

  13. JavaScript Check if Undefined

    We can also use the type of the variable to check if it's undefined. Luckily for us undefined is a datatype for an undefined value as you can see below: ‌. let name; console.log(typeof name); // "undefined". With this we can now use the datatype to check undefined for all types of data as we saw above.

  14. Optional chaining

    Summary. The optional chaining ?. syntax has three forms:. obj?.prop - returns obj.prop if obj exists, otherwise undefined.; obj?.[prop] - returns obj[prop] if obj exists, otherwise undefined. obj.method?.() - calls obj.method() if obj.method exists, otherwise returns undefined. As we can see, all of them are straightforward and simple to use. The ?. checks the left part for null ...

  15. Expressions and operators

    The shorthand assignment operator += can also be used to concatenate strings. For example, var mystring = 'alpha'; mystring += 'bet'; // evaluates to "alphabet" and assigns this value to mystring. Conditional (ternary) operator. The conditional operator is the only JavaScript operator that takes three operands. The operator can have one of two ...

  16. In JavaScript, how to conditionally add a member to an object?

    Create your object using an anonymous constructor and always assign undefined members to the same dummy member which you remove at the very end. This will give you a single line (not too complex I hope) per member + 1 additional line at the end. var a = new function() {. this.AlwaysPresent = 1;

  17. if...else

    Do not confuse the primitive Boolean values true and false with truthiness or falsiness of the Boolean object. Any value that is not false, undefined, null, 0, -0, NaN, or the empty string (""), and any object, including a Boolean object whose value is false, is considered truthy when used as the condition. For example:

  18. Optional chaining (?.)

    You can use optional chaining when attempting to call a method which may not exist. This can be helpful, for example, when using an API in which a method might be unavailable, either due to the age of the implementation or because of a feature which isn't available on the user's device. Using optional chaining with function calls causes the ...

  19. javascript

    @Hortitude: That's point (4). I generally wouldn't typeof foo=='undefined'; it tends to be used for (4a) global-sniffing, in which case I'd prefer to be explicit and say 'foo' in window, or (4b) testing against the undefined-value itself, in which case I'd prefer to be readable and say foo===undefined.In theory testing typeof against 'undefined' could have a use case that other constructs ...

  20. Destructuring assignment

    Unpacking values from a regular expression match. When the regular expression exec() method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to unpack the parts out of this array easily, ignoring the full match if ...

  21. Destructuring assignment

    The ( ..) around the assignment statement is required syntax when using object literal destructuring assignment without a declaration. {a, b} = {a: 1, b: 2} is not valid stand-alone syntax, as the {a, b} on the left-hand side is considered a block and not an object literal. However, ({a, b} = {a: 1, b: 2}) is valid, as is var {a, b} = {a: 1, b: 2} NOTE: Your ( ..) expression needs to be ...