Values, Types & The Coercion Trap

JS-এর ৮টি type এবং coercion-এর ফাঁদ

~30 min Beginner 12 practice problems Live runner

1. The 8 Types of JavaScript

Every JavaScript value belongs to exactly one of 8 types. Seven are primitives (immutable, copied by value); the eighth is the catch-all object.

TypeExampleNotes
string"হ্যালো"UTF-16 text
number42, 3.14, NaNIEEE 754 64-bit float
booleantrue, falseTwo values only
nullnullIntentional absence
undefinedundefinedDefault for unset variables
symbolSymbol("id")Unique identifier (rare in beginner code)
bigint9007199254740993nArbitrary-precision integers
object{}, [], functionsEverything non-primitive
JavaScript-এ মোট ৮টি type — ৭টি primitive (string, number, boolean, null, undefined, symbol, bigint) এবং একটি object। Array, function — সবই object type-এর ভেতরে পড়ে।

2. The typeof Operator

typeof returns a string describing the type. It has one famous bug from 1995 that has never been fixed: typeof null === "object".

typeof.js
console.log(typeof "hi");          // "string"
console.log(typeof 42);            // "number"
console.log(typeof true);          // "boolean"
console.log(typeof undefined);     // "undefined"
console.log(typeof null);          // "object"  ← legacy bug
console.log(typeof {});            // "object"
console.log(typeof []);            // "object"  (Array.isArray helps)
console.log(typeof console.log); // "function"
console.log(typeof 10n);           // "bigint"
console.log(typeof Symbol("id"));   // "symbol"
Detecting arrays Use Array.isArray(x), never typeof x === "array" (no such type) or x instanceof Array (fails across iframes).

3. Coercion — Implicit vs Explicit

JS converts types automatically when an operator demands it. This is coercion, and it is the #1 source of beginner bugs.

Implicit (silent)
implicit.js
console.log(1 + "2");         // "12"   number → string
console.log("5" - 2);         // 3      string → number
console.log("5" * "2");       // 10
console.log(true + 1);        // 2     true → 1
console.log(false + "!");     // "false!"
console.log(null + 1);        // 1     null → 0
console.log(undefined + 1);   // NaN   undefined → NaN
console.log([] + []);          // ""
console.log([] + {});          // "[object Object]"
Explicit (you ask for it)
explicit.js
console.log(Number("42"));        // 42
console.log(Number("4.5"));       // 4.5
console.log(Number("hi"));        // NaN
console.log(String(3.14));        // "3.14"
console.log(Boolean(0));          // false
console.log(Boolean("hi"));       // true
console.log(parseInt("42px"));     // 42
console.log(parseFloat("3.14m")); // 3.14

4. == vs === — The Most Important Rule

== coerces before comparing. === never coerces — types must match. The community-wide rule for 2026: always use ===, with one rare exception (x == null to catch both null and undefined).

eq.js
console.log(0 == "");          // true   ← scary
console.log(0 == false);       // true
console.log("" == false);      // true
console.log(null == undefined); // true
console.log(1 == "1");         // true

console.log(0 === "");         // false  ← sane
console.log(0 === false);      // false
console.log(null === undefined);// false
console.log(1 === "1");        // false
Rule of thumb Configure ESLint with "eqeqeq": "error" and never look back. ==-related bugs cost the JS world millions of hours per year.

5. NaN & Infinity

NaN stands for "Not a Number" — yet its type is number. It is the result of any nonsensical numeric operation.

nan.js
console.log(0 / 0);                  // NaN
console.log(Number("abc"));            // NaN
console.log(typeof NaN);              // "number"
console.log(NaN === NaN);              // false  ← NaN ≠ NaN
console.log(Number.isNaN(NaN));         // true   ← correct way

console.log(1 / 0);                  // Infinity
console.log(-1 / 0);                 // -Infinity
console.log(Number.isFinite(42));       // true
NaN মানে Not a Number হলেও এর type "number"। এটি নিজেও নিজের সমান নয়। চেক করতে Number.isNaN(x) ব্যবহার করুন।

6. Primitives Are Copied by Value, Objects by Reference

copy.js
let a = 5;
let b = a;       // copy of 5
b = 99;
console.log(a, b);   // 5 99

const obj1 = { name: "Arif" };
const obj2 = obj1; // same reference!
obj2.name = "Nusrat";
console.log(obj1.name); // "Nusrat"  ← changed!

7. Glossary (শব্দকোষ)

TermMeaningবাংলায়
PrimitiveImmutable basic value — string, number, boolean, null, undefined, symbol, bigint.অপরিবর্তনীয় মৌলিক value — সাতটি প্রাথমিক type।
CoercionAutomatic type conversion when an operator demands it.Operator-এর প্রয়োজনে স্বয়ংক্রিয় type পরিবর্তন।
typeofOperator that returns a string naming the type of its operand.যেকোনো value-র type-এর নাম string হিসেবে দেয়।
NaN"Not a Number" — result of invalid math; type is number.Not a Number — অবৈধ math-এর ফলাফল; type হলেও "number"।
===Strict equality — compares value and type, no coercion.কঠোর সাম্য — type ও value দুটোই মেলায়।
==Loose equality — coerces before comparing. Avoid.শিথিল সাম্য — coerce করে compare করে। এড়িয়ে চলুন।
BigIntArbitrary-precision integer type, written with n suffix.যেকোনো বড় integer ধরে রাখার type — শেষে n লাগে।
ReferencePointer to an object in memory; copies share the same data.Memory-তে object-এর pointer; copy-গুলো একই data share করে।
মনে রাখার নিয়ম: JS-এ ৮টি type, ৭টি primitive। typeof null === "object" — ১৯৯৫ সালের bug। typeof []-ও "object" — array চেক করতে Array.isArray() ব্যবহার করুন। সবসময় ===; শুধু x == null-এ == grant করা যায় (null + undefined একসাথে চেক)। Primitive value copy হয়; object reference copy হয়।

8. Practice Problems

  1. Predict the output, then run: console.log(typeof null);
    ✨ Show Answer

    Output: "object" — a 1995 bug preserved for backward compatibility. To check for null, use x === null.

  2. Predict, then run: "5" + 3 and "5" - 3. Why are they different?
    ✨ Show Answer
    ans2.js
    console.log("5" + 3);   // "53"
    console.log("5" - 3);   // 2

    + string-এর সাথে concat করে; - শুধু সংখ্যায় কাজ করে, তাই string-কে number-এ coerce করে।

  3. List all 6 falsy values in JavaScript and verify them with Boolean().
    ✨ Show Answer
    ans3.js
    [false, 0, "", null, undefined, NaN]
        .forEach(v => console.log(v, "→", Boolean(v)));
  4. Why does NaN === NaN return false? How should we test for NaN?
    ✨ Show Answer

    Answer: The IEEE 754 spec defines NaN as never-equal-to-anything, including itself, so any test against NaN with === returns false. Use Number.isNaN(x) — it returns true only for the genuine NaN value.

    IEEE 754 specification অনুসারে NaN কখনো নিজের সমান নয়। চেক করতে Number.isNaN(x) ব্যবহার করুন।

  5. Show the result of 1 == "1", 1 === "1", null == undefined, null === undefined.
    ✨ Show Answer
    ans5.js
    console.log(1 == "1");         // true
    console.log(1 === "1");        // false
    console.log(null == undefined); // true
    console.log(null === undefined);// false
  6. Convert the string "42" to a number using three different methods.
    ✨ Show Answer
    ans6.js
    console.log(Number("42"));       // 42
    console.log(parseInt("42", 10));  // 42
    console.log(+"42");             // 42 (unary +)
  7. Why does typeof [] return "object"? How would you correctly check for an array?
    ✨ Show Answer

    Arrays are objects under the hood — typeof only knows the broad category. Use Array.isArray(x) for a reliable check.

    ans7.js
    console.log(typeof []);          // "object"
    console.log(Array.isArray([]));  // true
    console.log(Array.isArray({})); // false
  8. Demonstrate that primitive copy is by value, but object copy is by reference.
    ✨ Show Answer
    ans8.js
    let p1 = 10; let p2 = p1; p2 = 99;
    console.log("primitive:", p1, p2);    // 10 99
    
    const o1 = { x: 1 }; const o2 = o1;
    o2.x = 99;
    console.log("object   :", o1.x, o2.x);   // 99 99
  9. Predict the output: [] + [], [] + {}, {} + [].
    ✨ Show Answer

    [] + [] → "" (both coerce to empty string). [] + {} → "[object Object]". {} + [] can be 0 or "[object Object]" depending on whether {} is parsed as a block (in REPL) or an object (in expression).

    এই কারণে JS-এ পেশাদার কোডে কখনো এমন expression লিখবেন না। সর্বদা cast করুন বা JSON.stringify ব্যবহার করুন।

  10. Use Number.isInteger to verify three test values: 5, 5.5, and "5".
    ✨ Show Answer
    ans10.js
    console.log(Number.isInteger(5));     // true
    console.log(Number.isInteger(5.5));   // false
    console.log(Number.isInteger("5"));   // false (strict)
  11. Build a function type(x) that returns "array", "null", or typeof x — fixing the two famous bugs.
    ✨ Show Answer
    ans11.js
    function type(x) {
        if (x === null) return "null";
        if (Array.isArray(x)) return "array";
        return typeof x;
    }
    console.log(type(null));   // "null"
    console.log(type([]));     // "array"
    console.log(type(42));     // "number"
    console.log(type("hi"));   // "string"
  12. In one paragraph, explain why === should be your default and when == is acceptable.
    ✨ Show Answer

    Answer: === compares both type and value, so it never lies. == performs implicit coercion using a 12-step algorithm few developers fully memorise — and the surprises (0 == "", [] == false) cause real production bugs. The single defensible use of == is the idiom x == null, which catches both null and undefined in one expression. Outside that, configure your linter to forbid ==.

    === type ও value দুটোই মেলায়, তাই কখনো ভুল করে না। == ১২-ধাপের coercion algorithm চালায় যা মনে রাখা কঠিন। শুধু x == null idiom-টি গ্রহণযোগ্য।

Summary — Module 04

JavaScript has 8 types: 7 primitives + object. typeof null wrongly returns "object"; typeof [] returns "object" too — use Array.isArray. Coercion is automatic — + with a string concatenates; everything else converts to numbers. Always use ===; the only exception is x == null. Primitives copy by value; objects (including arrays) copy by reference.

JS-এ ৮ type, যার মধ্যে ৭টি primitive। typeof-এর দুটি বিখ্যাত bug মনে রাখুন। সবসময় ===। Primitive value copy হয়, object reference copy হয়।

Next Module → Operators, Expressions & Truthy/Falsy — সকল অপারেটর এক জায়গায়।