The question mark (?) has taken on important new roles in JavaScript beyond just denoting questions. With the addition of features like the ternary operator, nullish coalescing, and optional chaining, the ? symbol has become an invaluable tool for writing cleaner and safer code.
But what do all these new instances of ? actually do? You may have seem them pop up in code examples online or new framework source code, but not fully understand their purpose.
As a full-stack developer well-versed in modern JavaScript practices, I want to provide a definitive guide to the most common uses of ? in JavaScript. By the end, the question mark won‘t seem so questionable!
A Brief History of ? in JavaScript
Before we dive into practical examples, a quick history lesson is in order.
The ternary operator in JavaScript (and many other C-style languages) has been around for decades. Offering a condensed syntax for if/else statements, it has always been popular with experienced developers.
However, the more recent rise of ? can be traced to innovations spearheaded by TC39 – the technical committee governing JavaScript standards.
In 2014, the nullish coalescing operator was proposed as a way to better handle default values when variables are null/undefined. This entered the JavaScript language specification in 2020.
Optional chaining followed a similar trajectory, providing a safe way to traverse nested object structures with questionable or missing data. This was accepted in 2019.
So while ? has been in JavaScript for conditional (ternary) expressions for a long time, ?? and ?. build on top of that to handle modern code challenges.
Now let‘s explore each of these use cases more in depth.
Ternary Operator (? shorthand for if/else)
The ternary operator provides shorthand syntax for basic conditional logic. Let‘s compare the traditional if/else approach to the ternary operator:
Traditional If/Else
let age = 17;
let message;
if (age >= 18) {
message = "You are eligible to vote";
} else {
message = "You must be 18+ to vote";
}
console.log(message)
// "You must be 18+ to vote"
With Ternary Operator
let age = 17;
let message = (age >= 18) ? "You are eligible to vote" : "You must be 18+ to vote";
console.log(message);
// "You must be 18+ to vote"
As you can see, the ternary operator allows us to assign message based on a condition in one line instead of using block syntax.
Some key notes on syntax:
- Condition goes first, followed by ?
- The expressionIfTrue is returned if condition is truthy
- Otherwise expressionIfFalse is returned
- These expressions are separated by :
This provides a very concise way to write basic conditional logic. Expression branches even allow function calls or more complex JavaScript syntax too.
Now for a more realistic example:
function getFee(members) {
return (members > 1000) ? members * 0.05 : members * 0.1;
}
getFee(2000) // Returns 100 - 5% of 2000
getFee(500) // Returns 50 - 10% of 500
In this case using a ternary operator made sense:
- We had a simple true/false conditional check
- Needed to return one of two very small expressions
- No need for more complex multi-line logic
Some use cases where ternary shines:
- Quick conditional returns/assignments
- Formatting strings based on state
- Toggle simple UI display properties
- Conditionally applying class names
However, be careful when:
- Nested too deep (can harm readability)
- Expressions get overly complex
- Multi-line code is needed
With great power comes great responsibility! To keep your code clean, only use ternary where it makes logical sense over classic conditional block syntax.
Nullish Coalescing Operator (??)
JavaScript can be quite strict when a variable is null or undefined – trying to access properties of those values will throw errors.
The nullish coalescing operator was added to give developers easier fallback defaults when dealing with potentially empty variables:
let username = null;
let displayname = username ?? "Anonymous";
// displayname = "Anonymous"
The syntax:
let assignedVar = maybeNullVar ?? alternateValue;
The left side operand gets returned if it has a value. But if it‘s null/undefined, alternateValue on the right gets set instead.
This provides a safer default behavior vs. typical OR (||) logic:
let username = null;
let displayname = username || "Anonymous";
// Runs into issues if username is ever falsy but not null
Having specific null/undefined handling makes many cases easier without needing to expressly check variable state:
// Fetch user from API
let userData = fetchUser();
// Use data if available, fallback if API returned null
let username = userData?.name ?? "Guest";
It‘s often used for:
- Fallback values when fetching external data
- Sensible defaults when accepting user input
- Safer destructuring of potentially empty objects
Usage grew 5x from 2018 to 2022 according to NPM download statistics:

This shows it filling an important niche in modern codebases.
However, not universally supported in legacy browsers. Be sure to transpile code for production when using ?? syntax.
Overall the nullish coalescing operator makes handling nulls and empty values much simpler. Next let‘s explore how optional chaining builds on this.
Optional Chaining (?.)
Dealing with nested properties and unpredictable data structures is a fact of life in JavaScript. APIs return incomplete JSON. External libraries may have null fields.
Trying to access a nested value with normal dot notation fails fast if any reference in the chain is null/undefined:
user.address.street // Throws error if user.address is null
Optional chaining avoids this issue by simply returning undefined when a broken link in the chain is encountered:
let street = user?.address?.street;
street === undefined // Instead of crashing
The ?. checks each reference in the chain (user, address, street) before attempting the next property access. If anything comes back null/undefined, it short circuits and returns undefined.
Other syntax forms:
// Function calls
let age = user?.getAge();
// Array index
let firstOrder = user.orders?.[0]
This technique has exploded in popularity among frontend frameworks and libraries:
Popularity of @babel/plugin-proposal-optional-chaining over time [source: npm-stat.com]
It avoids needing explicitly null checks on every nested property – cleaner code while safely traversing objects.
Use cases where ?. shines:
- Safely accessing data from external APIs
- Pulling values from JSON responses
- Debugging complex objects
- Abstracting data access through layers
Downsides to consider:
- Can hide errors in production if not careful
- Overuse could indicate poor data validation
- Slight runtime cost when heavily applied
So while very useful, sprinkle ?. judiciously and complement with schema validation.
Putting It All Together: When to Use Which
We‘ve covered the major interpretations of ? in modern JavaScript, but when should each be applied? Here is a decision tree based on common use cases:
| You need to: | Solution: |
|---|---|
| Write concise conditional statement/return based on boolean condition | Ternary |
| Check if value is null/undefined with fallback default | Nullish coalescing |
| Traverse deep JSON/objects safely without errors | Optional chaining |
| Simplify small if/else statement | Ternary |
| Validate complex schemas | JS libraries |
| Access nested state in React UIs | Optional chaining |
| Handle incomplete API responses | Nullish coalescing or optional chaining |
The ternary operator is ideal for quick true/false conditional logic while nullish coalescing handles issues of empty values. Optional chaining shines when accessing properties on uncertain object structures.
Deciding when each is most appropriate takes practice – no perfect formulas. But the above guidelines provide a solid starting point for most cases.
And in general, lean towards readability. These operators improve safety and concision but overuse can harm legibility. Stick by basic principles of clean code and ? will slot nicely into that toolbox.
Common Misconceptions
With new syntax inevitably comes confusion during the learning process. Let‘s dispel some frequent misconceptions about ? in JavaScript:
Myth: ? and ?? are interchangeable
While related, these serve different purposes. ?? provides nullish default values while ?. avoids errors when traversing objects.
Myth: Optional chaining is the same as checking if value is undefined/null
Optional chaining handles traversal issues but does not perform logical null checks. Use ?? or strict equality checks for that.
Myth: Ternary expressions must fit on one line
The concise syntax allows one-liners but statements can be multi-line by wrapping in parens or breaking after ?/:
let message = (age >= 18)
? "Eligible"
: "Underage";
Myth: Ternary and if/else logic accomplish the same thing
While both allow conditional logic, ternaries have limitations in complexity/readability. Know when block syntax is more appropriate.
Recommended Practices
Based on hundreds of code reviews and own experience, here are my top tips for clean usage of ?:
- Limit nesting: Just like if/else statements, nested ternary expressions harm readability
- Use judiciously: Reserve for straightforward conditionals and handling uncertainty
- Complement with validation: Don‘t lean solely on optional chaining without data checks
- Check browser support: Transpile down syntax for legacy browser compatibility
- Parenthesize for multi-line: Use parens or backticks for split ternary/nullish statements
- Compare vs if/else syntax: Weigh both options during implementation
- Watch for duplication: If ternary logic appears 2+ times, extract into reusable function
Adopting these practices will ensure you leverage ? appropriately for cleaner and more resilient code.
Syntax Comparisons
Here is a quick reference guide contrasting the syntax variants of ? covered in JavaScript:
| Operator | Typical Syntax | Handling if Left Null/Undefined | Key Difference |
|---|---|---|---|
| Ternary | condition ? (ifTrue) : (ifFalse) |
n/a | Evaluates a simple true/false conditional |
| Nullish coalescing | leftExpr \?</? rightExpr |
Returns rightExpr |
Specifically checks nullish values with fallback |
| Optional chaining | obj?.prop |
Returns undefined |
Allows safe nested property access |
So in summary:
- Ternary: Conditional assignment/return
- Nullish coalescing: Fallback values
- Optional chaining: Traversal safety
Each variant has a distinct syntax and purpose.
Understanding how they complement each other provides a toolbox to handle most assessment and data access use cases in JavaScript.
Browser Compatibility
As newer language features, optional chaining and nullish coalescing may not work across all legacy browsers.
Here is a compatibility matrix as of December 2022:
| Operator | Chrome | Firefox | Safari | IE11 |
|---|---|---|---|---|
| Ternary | ✓ | ✓ | ✓ | ✓ |
| Nullish coalescing | ✓ | ✓ | ✓ | ❌ |
| Optional chaining | ✓ | ✓ | ✓ | ❌ |
So while ternaries have been in JS for ages, the other ? features require transpilation for full cross-browser function.
Many build pipelines/bundlers like Webpack automatically transform modern syntax. But if targeting legacy platforms, ensure Babel or TypeScript compilation.
For even wider JavaScript support, transpile down to ES5 level code. Third party polyfills also available:
So check your browser coverage requirements before adopting ?. syntax freely. Safest to assume need for compilation.
Frequently Asked Questions
Let‘s cover some common developer questions around usage of ? in JavaScript:
Q: What is the difference between ? and ?? operators?
The nullish coalescing ?? provides null/undefined handling while ?. enables safer nested property access. Very distinct behavior.
Q: When should I use ternary vs traditional if/else statements?
Ternaries shine for concise true/false logic but if/else blocks allow more complex conditional code. Use judgement based on specific need.
Q: How much slower are these operators compared to equivalent code?
marginally slower mostly
Q: How do I use ternary expressions across multiple lines?
Wrap the logic in parentheses or break up statements across lines after the ? and : separators.
Q: What is the best way to "polyfill" support for ?? and ?. syntax?
Transpilers like Babel handle this automatically. Can also use explicit shims but not recommended over automated builds.
I hope this thorough explainer dispels any question marks around the question mark in JavaScript!
In Summary
JavaScript has embraced ? in recent years to provide simpler conditional handling, property access, and fallback defaults.
Ternary operator expressions let developers replace if/else statements with concise true/false logic.
The nullish coalescing operator provides variable placeholders when values are null/undefined.
Optional chaining improves traversing nested structures without runtime errors.
Together these features present cleaner and more resilient data management options. Understanding the modern ? syntax makes one a better JavaScript developer.
So no more confusion when you encounter ? in examples online or new codebases! This guide explored all major applications along with appropriate usage, limitations, and misconceptions.
The question mark matches JavaScript‘s fluid nature – adapting based on developer needs over time. And JavaScript‘s future likely holds more clever applications of ? just waiting to be uncovered.


