Overview

4 Primitives, Coercion, and Equality

JavaScript’s primitive values are powerful precisely because they are simple, but the chapter shows how quickly trouble begins when those values interact. It opens with examples where checks like if (!transactionId) or == true cause real production bugs, then explains that the language’s flexibility comes with automatic conversions that can silently change meaning and hide problems until data reaches unexpected shapes or sizes. The main lesson is that JavaScript often “helps” by converting values for you, but that help can easily become a liability.

The chapter then clarifies the distinct roles of the primitive types. undefined and null both represent nothing, but in different ways: one suggests something was never assigned or looked up, while the other signals an intentional absence. Booleans are also trickier than they first appear because JavaScript uses truthy and falsy rules, meaning values like 0, '', and null behave as false in conditions while many other values, including empty arrays and objects, remain truthy. Symbols complete the primitive set by providing guaranteed-unique identifiers, which makes them useful for avoiding property-name collisions and supporting built-in language protocols, while runtime implementations such as V8 represent many primitive values very efficiently using immediate, pointer-tagged forms.

Finally, the chapter explains where coercion happens and why it matters. Arithmetic, comparisons, logical expressions, template literals, and many built-in functions all convert values according to specific rules, with the plus operator favoring strings, relational operators sometimes comparing text alphabetically, and loose equality performing multiple conversions before comparison. The chapter emphasizes that repeated coercion can hurt performance, especially inside loops and sort callbacks, and that chained conversions can yield surprising results such as [] == false being true while if([]) still runs. The practical guidance is to convert at boundaries, prefer strict equality, and use nullish checks when you want to treat only null and undefined as “no value.”

Summary

  • JavaScript distinguishes between undefined (not yet assigned) and null (intentionally empty) to represent different kinds of nothing
  • Nine specific values are falsy in conditions: undefined, null, false, 0, -0, 0n, -0n, NaN, and empty string—everything else is truthy
  • Symbols guarantee unique property keys, enabling libraries to extend objects without breaking existing code
  • Type coercion occurs automatically in arithmetic operators, comparisons, template literals, and many built-in methods
  • The plus operator prefers string concatenation while minus, multiply, and divide always convert to numbers
  • Loose equality (==) performs type coercion following complex rules, while strict equality (===) never coerces
  • Converting data once at system boundaries instead of repeatedly in loops prevents major performance bottlenecks
  • V8 represents null, undefined, and booleans as immediate values using pointer tagging for zero-allocation access

FAQ

What is the difference between undefined and null in JavaScript?

undefined usually means a value was not assigned, not found, or not provided, while null means a value was intentionally set to “nothing.” In practice, undefined is often used for uninitialized or missing values, and null for explicitly empty ones.

When should I use val == null instead of strict equality checks?

Use val == null when you want to catch both null and undefined at the same time. This is one of the rare cases where loose equality is useful because it matches both kinds of “nothing” with a single check.

Which JavaScript values are falsy?

The falsy values are undefined, null, false, 0, -0, 0n, -0n, NaN, and the empty string ''. Every other value is truthy.

Why can a value like '0' be truthy but still cause bugs in conditionals?

Because '0' is a non-empty string, it is truthy in a condition. But code that uses if (!value) or similar checks may treat other meaningful values like 0 or '' as if they were missing, which can cause logic bugs.

What does the double-bang operator !! do?

!! converts a value to a boolean. The first ! turns the value into its boolean opposite, and the second ! flips it back, leaving a real true or false value.

How do &&, ||, and ?? differ?

&& returns the first falsy value or the last truthy one, || returns the first truthy value or the last falsy one, and ?? only treats null and undefined as “empty.” Use ?? when 0 or '' should be preserved.

Why are symbols useful in JavaScript?

Symbols provide guaranteed-unique values that can be used as property keys. They help avoid naming collisions when libraries or frameworks need to attach metadata or special behavior to objects.

What is the difference between Symbol('x') and Symbol.for('x')?

Symbol('x') creates a new unique symbol every time, even if the description is the same. Symbol.for('x') looks up or creates a shared symbol in the global symbol registry, so repeated calls with the same key return the same symbol.

What is the main difference between == and ===?

== performs type coercion before comparing values, while === does not coerce at all. In most cases, === is safer and more predictable.

Where does type coercion happen automatically in JavaScript?

Type coercion happens in arithmetic operations, comparisons, logical contexts, template literals, and many built-in methods. For example, subtraction converts to numbers, + may convert to strings, conditions convert values to booleans, and methods like parseInt or Math.max may coerce their inputs.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • JavaScript in Depth ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • JavaScript in Depth ebook for free