• JavaScript
  • JavaScript
  • Tutorials and guides
  • Beginner's tutorials
    1. JavaScript Guide
      1. Loops and iteration
      2. Representing dates & times
      3. Working with objects
      4. Iterators and generators
      5. Asynchronous JavaScript
      6. Equality comparisons and sameness
      7. Meta programming
      8. AggregateError
      9. AsyncGenerator
      10. BigInt
      11. DataView
      12. encodeURI()
      13. escape() Deprecated
      14. Float16Array
      15. Generator
      16. Int8Array
      17. InternalError Non-standard
      18. Iterator
      19. NaN
      20. parseInt()
      21. ReferenceError
      22. SharedArrayBuffer
      23. Temporal Experimental
      24. Uint8ClampedArray
      25. unescape() Deprecated
      26. WeakSet
  • Assignment (=)
  • Bitwise AND (&)
  • Bitwise OR assignment (|=)
  • Comma operator (,)
  • Destructuring
  • Exponentiation (**)
  • Greater than (>)
  • import.meta.resolve()
  • Inequality (!=)
  • Less than (<)
  • Logical NOT (!)
  • Multiplication assignment (*=)
  • Nullish coalescing assignment (??=)
  • Optional chaining (?.)
  • Right shift (>>)
  • Strict inequality (!==)
  • this
  • Unsigned right shift (>>>)
  • yield*
  • Block statement
  • continue
  • export
  • for...in
  • if...else
  • let
  • try...catch
  • with Deprecated
  • get
  • The arguments object
    1. callee Deprecated
    2. extends
    3. Static initialization blocks
  • Character class escape: \d, \D, \w, \W, \s, \S
  • Input boundary assertion: ^, $
  • Modifier: (?ims-ims:...)
  • Quantifier: *, +, ?, {n}, {n,}, {n,m}
  • Errors
    1. RangeError: argument is not a valid code point
    2. RangeError: invalid array length
    3. RangeError: repeat count must be less than infinity
    4. ReferenceError: assignment to undeclared variable "x"
    5. SyntaxError: 'arguments'/'eval' can't be defined or assigned to in strict mode code
    6. SyntaxError: \ at end of pattern
    7. SyntaxError: await is only valid in async functions, async generators and modules
    8. SyntaxError: continue must be inside loop
    9. SyntaxError: function statement requires a name
    10. SyntaxError: identifier starts immediately after numeric literal
    11. SyntaxError: invalid assignment left-hand side
    12. SyntaxError: invalid class set operation in regular expression
    13. SyntaxError: invalid property name in regular expression
    14. SyntaxError: invalid unicode escape in regular expression
    15. SyntaxError: missing ) after argument list
    16. SyntaxError: missing } after property list
    17. SyntaxError: missing variable name
    18. SyntaxError: numbers out of order in {} quantifier.
    19. SyntaxError: property name __proto__ appears more than once in object literal
    20. SyntaxError: rest parameter may not have a default
    21. SyntaxError: super() is only valid in derived class constructors
    22. SyntaxError: unlabeled break must be inside loop or switch
    23. TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed
    24. TypeError: "x" is not a function
    25. TypeError: BigInt value can't be serialized in JSON
    26. TypeError: can't convert BigInt to number
    27. TypeError: can't redefine non-configurable property "x"
    28. TypeError: class constructors must be invoked with 'new'
    29. TypeError: Initializing an object twice is an error with private fields/methods
    30. TypeError: Iterator/AsyncIterator constructor can't be used directly
    31. TypeError: property "x" is non-configurable and can't be deleted
    32. TypeError: X.prototype.y called on incompatible type
    33. JavaScript technologies overview
    34. Strict mode
    35. Learn more
    36. See full compatibility
  • The nullish coalescing (??) operator is a logical operator that returns its right-hand side operand when its left-hand side operand is undefined, and otherwise returns its left-hand side operand.

    Try it

    const foo = null ?? "default string";
    console.log(foo);
    / Expected output: "default string"
    
    const baz = 0 ?? 42;
    console.log(baz);
    / Expected output: 0
    

    Syntax

    js
    leftExpr ?? rightExpr
    

    Description

    The nullish coalescing operator can be seen as a special case of the 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 consider some falsy values as usable (e.g., '' or 0). See below for more examples.

    The nullish coalescing operator has the fifth-lowest conditional (ternary) operator.

    It is not possible to combine both the AND (&&) and OR operators (||) directly with ??. A syntax error will be thrown in such cases.

    js
    null || undefined ?? "foo"; / raises a SyntaxError
    true && undefined ?? "foo"; / raises a SyntaxError
    

    Instead, provide parenthesis to explicitly indicate precedence:

    js
    (null || undefined) ?? "foo"; / returns "foo"
    

    Examples

    Using the nullish coalescing operator

    In this example, we will provide default values but keep values other than null or undefined.

    js
    const nullValue = null;
    const emptyText = ""; / falsy
    const someNumber = 42;
    
    const valA = nullValue ?? "default for A";
    const valB = emptyText ?? "default for B";
    const valC = someNumber ?? 0;
    
    console.log(valA); / "default for A"
    console.log(valB); / "" (as the empty string is not null or undefined)
    console.log(valC); / 42
    

    Assigning a default value to a variable

    Earlier, when one wanted to assign a default value to a variable, a common pattern was to use the logical OR operator (||):

    js
    let foo;
    
    / foo is never assigned any value so it is still undefined
    const someDummyText = foo || "Hello!";
    

    However, due to || being a boolean logical operator, the left-hand-side operand was coerced to a boolean for the evaluation and any falsy value (including 0, '', NaN, false, etc.) was not returned. This behavior may cause unexpected consequences if you consider 0, '', or NaN as valid values.

    js
    const count = 0;
    const text = "";
    
    const qty = count || 42;
    const message = text || "hi!";
    console.log(qty); / 42 and not 0
    console.log(message); / "hi!" and not ""
    

    The nullish coalescing operator avoids this pitfall by only returning the second operand when the first one evaluates to either null or undefined (but no other falsy values):

    js
    const myText = ""; / An empty string (which is also a falsy value)
    
    const notFalsyText = myText || "Hello world";
    console.log(notFalsyText); / Hello world
    
    const preservingFalsy = myText ?? "Hi neighborhood";
    console.log(preservingFalsy); / '' (as myText is neither undefined nor null)
    

    Short-circuiting

    Like the 'OR' and 'AND' logical operators, the right-hand side expression is not evaluated if the left-hand side proves to be neither null nor undefined.

    js
    function a() {
      console.log("a was called");
      return undefined;
    }
    function b() {
      console.log("b was called");
      return false;
    }
    function c() {
      console.log("c was called");
      return "foo";
    }
    
    console.log(a() ?? c());
    / Logs "a was called" then "c was called" and then "foo"
    / as a() returned undefined so both expressions are evaluated
    
    console.log(b() ?? c());
    / Logs "b was called" then "false"
    / as b() returned false (and not null or undefined), the right
    / hand side expression was not evaluated
    

    Relationship with the optional chaining operator (?.)

    The nullish coalescing operator treats undefined and null as specific values. So does the optional chaining operator (?.), which is useful to access a property of an object which may be null or undefined. Combining them, you can safely access a property of an object which may be nullish and provide a default value if it is.

    js
    const foo = { someFooProp: "hi" };
    
    console.log(foo.someFooProp?.toUpperCase() ?? "not available"); / "HI"
    console.log(foo.someBarProp?.toUpperCase() ?? "not available"); / "not available"
    

    Specifications

    Specification
    ECMAScript® 2026 Language Specification
    # prod-CoalesceExpression

    Browser compatibility

    See also