October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

10 JavaScript Behaviors That Look Weird Until You Understand the Rules

Why is an empty array truthy? Why is NaN unequal to itself? Learn the JavaScript rules behind 10 surprising results—and the checks that make code clearer.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

JavaScript’s strangest-looking results usually follow a small set of rules: implicit type conversion, truthiness, equality, and the difference between declaring a variable and initializing it. Knowing which rule applies makes expressions easier to debug—and helps you write clearer checks.

1. Why does typeof null return "object"?

null is a primitive value, but typeof null returns "object". This is a longstanding compatibility quirk, not evidence that null is an object. For a direct null check, use strict equality:

As an Amazon Associate I earn from qualifying purchases.

if (value === null) {
  // value is null
}

MDN explains the distinction in its JavaScript data types and data structures guide.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Why is NaN a number that is unequal to itself?

NaN is a special numeric value, often produced when a numeric operation cannot yield a valid number. Its type is still number, but equality comparisons involving it are false—including comparison with itself:

typeof NaN; // "number"
NaN === NaN; // false

Use Number.isNaN(value) to test specifically for it; equality is not a reliable NaN test. MDN covers NaN in its data types guide and describes the equality rules in Equality comparisons and sameness.

3. Why can + mean either concatenation or addition?

The plus operator depends on the operands after JavaScript converts them to primitives. If that conversion results in a string operand, + concatenates; otherwise, it performs numeric addition. Since the operations are evaluated left to right, changing the order changes the result:

"3" + 4 + 5; // "345"
// First: "3" + 4 → "34"; then: "34" + 5 → "345"

3 + 4 + "5"; // "75"
// First: 3 + 4 → 7; then: 7 + "5" → "75"

When an expression mixes strings and numbers, make the intended conversion explicit or split the work into named steps. MDN explains the operator and conversion behavior in its data types guide and JavaScript language overview.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Why can == treat different types as equal?

Loose equality applies a set of conversion rules before comparing some values. For example, the Boolean in 1 == true is converted to a number, making the comparison equivalent to 1 == 1. Strict equality does not equate values of different types:

1 == true;  // true
1 === true; // false

The loose-equality algorithm has special cases for nullish values, strings, BigInts, and objects; it does not simply convert every value to a number. For ordinary comparisons, === is usually easier to reason about because it avoids these implicit conversions. See MDN’s equality guide and language overview.

5. Why are empty arrays and objects truthy?

JavaScript’s truthiness rule does not treat “empty” as false. An empty array or object is truthy, so each enters the if block:

if ([]) {
  // runs
}

if ({}) {
  // also runs
}

The falsy values are false, 0, -0, 0n, "", NaN, null, and undefined. Other values are truthy. To check whether an array is empty, test its length instead:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
if (items.length === 0) {
  // items is empty
}

MDN lists these rules in its JavaScript language overview.

6. Why do && and || return values instead of Booleans?

Logical operators short-circuit based on truthiness, but return one of their operands—not a normalized true or false. For &&, JavaScript returns the first falsy operand, or the last operand if all are truthy. For ||, it returns the first truthy operand, or the last operand if none is truthy:

0 && "ready";          // 0
"ready" && "next";     // "next"
"" || "fallback";      // "fallback"
"ready" || "fallback"; // "ready"

This behavior supports idioms such as value && value.property, but optional chaining is often clearer when the intent is to access a property only if a value is not nullish:

value?.property

The operator return rules are described in MDN’s language overview.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

7. Why can a var declared inside a block be used outside it?

var is scoped to its containing function, or to the global scope when declared outside a function. An if block does not create a scope for a var binding:

if (true) {
  var message = "available";
}

console.log(message); // "available"

By contrast, let and const are block scoped. If a value should exist only inside a block, use one of those declarations. MDN outlines these distinctions in its grammar and types guide.

8. What does hoisting actually mean?

“Hoisting” is a shorthand for how declarations are available within their scope; JavaScript does not literally move source lines. The outcome depends on the declaration type:

var: binding available as undefined

A var binding is initialized to undefined before its assignment runs. Reading it earlier does not retrieve the later assigned value:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
console.log(count); // undefined
var count = 3;

let and const: temporal dead zone

These bindings exist in their scope but cannot be accessed before execution reaches their declaration. Accessing one too early throws a ReferenceError:

console.log(total); // ReferenceError
let total = 3;

Function declarations: available earlier in scope

A function declaration can be called before its position in the source code:

greet(); // "hello"

function greet() {
  return "hello";
}

MDN discusses scope, initialization, and function declarations in its grammar and types guide.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

9. Why does document.all behave like undefined in some checks?

document.all is a browser-specific, legacy compatibility exception. The HTML platform gives this host-defined object special behavior in selected operations: it is falsy, loosely equal to null or undefined, and has the typeof result "undefined". Those behaviors do not make it an ordinary undefined value or establish a general rule for objects.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
typeof document.all;      // "undefined"
Boolean(document.all);    // false
document.all == null;     // true

This exception is documented in MDN’s equality guide and specified in ECMA-262, 12th edition, Annex B.3.7.

10. How can objects and arrays change an expression through conversion?

When an operation needs a primitive value from an object, JavaScript may consult the object’s [Symbol.toPrimitive] method, then its valueOf and toString methods according to the conversion rules. The resulting primitive can affect concatenation or equality. For instance, in an expression context, an ordinary object and an empty array can produce a string:

({} + []); // "[object Object]"

The parentheses make the expression context clear: a brace at the start of a statement can instead be parsed as a block, so brace-leading examples can behave differently depending on where they appear. When an expression’s result looks surprising, identify the conversion the operator requests and the primitive each operand supplies. MDN explains object-to-primitive conversion in its data types and data structures guide.

A practical way to debug a surprising expression

  • Write down each operand’s type before evaluating the operator.
  • Check whether the operator converts values, and whether evaluation order changes what gets converted next.
  • For a condition, distinguish truthiness from checks such as “is null” or “is an empty array.”
  • For variables, identify the declaration type and scope before assuming a value is available.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.