When working with JavaScript, we often need to set default configurations and allow users to override certain values. A common but flawed approach is using the logical OR (||) operator for defaults, which can lead to unexpected behavior. This article explains why || is problematic for object merging and how to correctly override defaults using the ES6 spread operator (...).
1. The Problem: Why || Falls Short
Consider this typical pattern:
const enabledEngines = this.settings?.enabledEngines || {
    baidu: true,
    google: true,
    bing: true,
    so: true,
    sogou: true
};Key Issues with ||:
- 
||Only Checks for Falsy Values, Failing to Overridefalse- If this.settings?.enabledEnginesis{ google: false }, the||operator won’t apply the fallback (since an object is truthy), incorrectly keepinggoogle: true.
- The fallback only triggers if the left side is undefined/null.
 
- If 
- 
No Partial Overrides - If a user only wants to disable one engine (e.g., { bing: false }),||forces a full replacement, discarding other defaults.
 
- If a user only wants to disable one engine (e.g., 
2. The Solution: Object Spread Operator (...)
The correct approach is to let user settings override defaults without discarding the entire object. The ES6 spread operator (...) solves this elegantly:
const enabledEngines = {
    baidu: true,
    google: true,
    bing: true,
    so: true,
    sogou: true,
    ...this.settings?.enabledEngines  // User settings override defaults
};Why This Works:
- Correctly Handles falseOverrides- If the user passes { google: false },googleis properly disabled while other defaults remain.
 
- If the user passes 
- Supports Partial Updates
- Users only need to specify changes; unspecified keys keep their defaults.
 
- Safer Than ||- Even an empty object {}won’t trigger an unwanted fallback.
 
- Even an empty object 
3. Real-World Examples
Case 1: User Disables Google
const userSettings = { google: false };
//  Wrong (||)
const badResult = userSettings || { google: true, bing: true };
// => { google: false } ( bing is lost!)
//  Right (...)
const goodResult = { google: true, bing: true, ...userSettings };
// => { google: false, bing: true } (Correct!)Case 2: No User Settings Provided
const userSettings = undefined;
//  Wrong (||)
const badResult = userSettings || { google: true };
// => { google: true } (Works but inflexible)
//  Right (...)
const goodResult = { google: true, ...userSettings };
// => { google: true } (Same outcome, but consistent)4. When Is || Acceptable?
While || isn’t ideal for objects, it’s still useful for:  
- Primitive defaults (e.g., string,number,boolean)const limit = userLimit || 10; // Fails if userLimit is 0!
- Full replacements (not merging)
const config = userConfig || defaultConfig; // Replaces entirely
For object merging, always prefer ....
