Recommended resources
The freely available resources this lesson will direct you to.
Hello! Last time, you ran a Node.js file and saw that a program can finish normally while producing the wrong answer. JavaScript’s value-conversion rules are one reason that happens: an expression can be valid code, yet calculate or compare something other than what you intended.
Today you’ll learn to predict the value and type of expressions involving primitives, coercion, and strict equality. That skill will help you catch quiet bugs in everyday Node.js code before they become incorrect decisions in an API.
Begin with the kind of value you have
A primitive is a JavaScript value such as a number, string, or boolean—not an object with properties you manage. This chart shows the broader landscape. For this lesson, concentrate on the primitive side; arrays and other objects have their own lessons later.

The primitives you’re most likely to encounter in today’s examples are:
- Numbers:
3,0,2.5 - Strings:
"3","","open"—even"3"is text, not a number - Booleans:
true,false null: a deliberate value often used to represent “no value”undefined: a value you may encounter when no value has been supplied
The chart also includes bigint and symbol. They are primitives too, but we won’t need their specialized uses to predict the expressions here. One historical oddity is worth knowing: typeof null evaluates to "object" even though null is a primitive.
The typeof operator lets you check the type of a result in Node:
console.log(typeof 3); // "number"
console.log(typeof "3"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
When an output looks right at first glance, its type may still be wrong. Printing 3 and printing "3" can look similar in a terminal; typeof exposes the distinction.
Conversion depends on the operation
Suppose a ticket count arrives as the string "3", and you want to add one. JavaScript does not apply one universal “turn text into numbers” rule. The operator determines what conversion, if any, occurs.
Watch the selected portions of #8 Type Conversion & Coercion in JavaScript from Telusko. The first part shows conversions requested explicitly with String() and Number(); the second contrasts what + and - do automatically.
#8 Type Conversion & Coercion in JavaScript
Watch Telusko's examples to distinguish a conversion you request from a conversion JavaScript performs while evaluating an operator.
Watch string conversion and number conversion for the explicit forms. Then watch string addition and numeric subtraction. Focus on which operation produces text and which produces a number.
Try the same distinction in a saved Node.js file:
console.log("3" + 1); // "31"
console.log("3" - 1); // 2
console.log(Number("3") + 1); // 4
With +, if either primitive operand is a string, JavaScript joins their string forms: "3" + 1 produces the string "31". With -, JavaScript performs numeric subtraction, converting "3" to the number 3 first. Number("3") makes that conversion explicit, so the final line performs numeric addition.
This is the connection to last lesson’s logical errors. If you meant to increment a count but used "3" + 1, Node reports no error. The program simply produces the wrong value for your requirement.
Read the numeric and boolean portions of Type Conversions in The Modern JavaScript Tutorial to see the conversion rules behind these examples.
This reading explains what explicit conversions such as Number(value) and Boolean(value) produce, including cases that are easy to mistake for zero or false.
In “Numeric Conversion,” begin where the author says numeric conversion. Read through the conversion table and the examples immediately beneath it, ending after the note contrasting null and undefined. Then, in “Boolean Conversion,” read from boolean conversion through the examples showing why both "0" and a space-only string are true. Focus on the value produced by each conversion, not just the printed appearance of that value.
For numeric conversion, these are useful checkpoints:
console.log(Number(" 3 ")); // 3
console.log(Number("")); // 0
console.log(Number(true)); // 1
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(Number("three")); // NaN
NaN means “not a number”: it is a numeric value representing an unsuccessful numeric result, not a thrown error. Despite its name, typeof NaN is "number". If numeric input must be valid, conversion alone is not enough; you must also check its result, for example with Number.isNaN().
Boolean conversion follows a different rule. Among the values used here, 0, NaN, "", null, and undefined convert to false; nonzero numbers and nonempty strings convert to true.
console.log(Boolean(0)); // false
console.log(Boolean("0")); // true
console.log(Boolean("")); // false
console.log(Boolean(" ")); // true
The string "0" is not the number 0, and " " is not an empty string—it contains a space. In the next lessons, these boolean results will matter when code chooses a branch.
Predict the whole expression, not just one operation
Evaluate an expression in its actual order, keeping track of each intermediate value and its type. For instance, addition is evaluated from left to right when the operators have the same precedence:
console.log(2 + 3 + "4"); // "54"
console.log("2" + 3 + 4); // "234"
In the first line, 2 + 3 produces the number 5; then 5 + "4" produces the string "54". In the second, "2" + 3 produces "23"; adding 4 joins more text. Parentheses make the intended grouping explicit:
console.log("2" + (3 + 4)); // "27"
The practical habit is to pause whenever a value came from text but you intend arithmetic. Convert it deliberately, and distinguish a failed conversion (NaN) from a valid number before relying on it.
Compare values without changing their meaning
Comparisons produce booleans, but different comparison operators use different rules. Read the selected parts of Comparisons in The Modern JavaScript Tutorial, paying particular attention to the separation between relational comparison, loose equality, and strict equality.
Comparisons - The Modern JavaScript Tutorial
This reading shows why two expressions that look like similar comparisons can give different answers.
In “String comparison,” start at string order and stop after the note about uppercase and lowercase letters. In “Comparison of different types,” read from the opening sentence “When comparing values of different types” through the examples converting strings and booleans; stop before “A funny consequence.” In “Strict equality,” read from equality rules through the explanation that strict equality does not convert different types. Finally, in “Comparison with null and undefined,” read the strict and non-strict examples, then the “Strange result: null vs 0” example and “Avoid problems.” Focus on which operator supplies the conversion rule in each case.
When both operands are strings, > compares them character by character, not as numbers:
console.log("2" > "12"); // true
At the first character, "2" sorts after "1", so the comparison is already decided. When a string is compared relationally with a number, JavaScript instead performs numeric conversion:
console.log("2" > 12); // false
For equality, prefer strict equality === when you want to know whether two primitive values match without type conversion:
console.log(3 === 3); // true
console.log("3" === "3"); // true
console.log("3" === 3); // false
console.log(false === 0); // false
console.log(null === undefined); // false
Different types make strict equality false. For values of the same type, their values must also match. Strict inequality, !==, gives the opposite answer to ===.
Loose equality, ==, may convert values. It can therefore give answers that are surprising if you expected strict equality:
console.log("3" == 3); // true
console.log(false == 0); // true
console.log(null == undefined); // true
console.log(null == 0); // false
Do not treat == as a simple instruction to convert both sides to numbers. null == undefined follows a special rule, while null == 0 is false. Relational comparisons follow yet another rule: null >= 0 is true because that comparison converts null to zero. The safest approach for ordinary application code is to use === by default and handle possibly missing values explicitly.
Here is a realistic consequence for a ticket count:
const storedCount = "3";
const expectedCount = 3;
console.log(storedCount === expectedCount); // false
console.log(Number(storedCount) === expectedCount); // true
The first comparison tells you the values are represented differently. The second states your intent: interpret the stored text as a number, then compare. If the text might be invalid, check the conversion before accepting it as a count.
Takeaways
To predict a JavaScript expression, identify each primitive’s type, evaluate operations in order, and apply the conversion rule for the specific operator. + can join strings, numeric operations can convert strings to numbers, and a failed numeric conversion can yield NaN without stopping the program. === compares without type conversion; == can convert and has special cases, so they are not interchangeable.
Next, you’ll use const, let, and block scope to keep these values in the right places as a program grows.