Understanding JavaScript Types: Practices, Common Mistakes, and Survival Tips
A practical article about types in JavaScript – from undefined to Symbol, with tips to help you avoid "silly" bugs that 99% of developers have made.
1. How many data types are there in JavaScript?
JavaScript classifies types into two main groups:
1.1 Primitive types
These are primitive data types, stored directly in the stack:
undefinednullbooleannumberstringbigint(ES2020)symbol(ES6)
1.2 Non-primitive types
There is only one non-primitive type: object, which includes:
- object literal:
{ } - array:
[ ] - function:
function() { } - date, regexp, v.v.
Tip: You can check the value type with typeof, but typeof null === 'object' is a bug that has been around for a long time in the history of javascript
2. typeof — do not trust
typeof null // "object" ← bug
typeof NaN // "number" ← ???
typeof [] // "object" ← Not clear
typeof (() => {}) // "function" ← OKTip: To check array, useArray.isArray(value)instead oftypeof.
3. Difference between undefined and null
undefined | null |
|---|---|
| Variable has not been assigned a value | Explicitly assigned to represent “no value” |
| Assigned by the interpreter itself | Assigned by developer |
let a;
console.log(a); // undefined
let b = null;
console.log(b); // nullCommon Bug: Compare==betwwennullandundefinedreturntrue, but===it not
null == undefined // true
null === undefined // false4. compre by == vs === – system destroyer
0 == false // true
"" == false // true
[] == false // true
[] == ![] // true ← ????
null == undefined // trueAdvise: Always use === to avoid weird result due to coercion.5. symbol and bigint — strangers (rarely used)
Symbol – unique data type is always distinct
const id1 = Symbol('id');
const id2 = Symbol('id');
console.log(id1 === id2); // falseUse cases: create conflict-free locks in object or enum safe.
BigInt
const max = BigInt(Number.MAX_SAFE_INTEGER);
console.log(max + 1n); // work fine
// Note: Can not mix with number
`123 + 1n // Error!6. Some classic typing errors in practice
1. Object vs Array
typeof {} // "object"
typeof [] // "object"
Array.isArray([]) // trueCommon bug: treating array as object or vice versa when doing deep clone, loop, etc.
2. Falsy value
const values = [false, 0, "", null, undefined, NaN];
values.forEach(v => {
if (!v) {
console.log(`"${v}" là falsy`);
}
});
Tip: If you need to check for exactly null or undefined, don't useif (!value)usevalue === null || value === undefined.
7. Tips typeof, instanceof, constructor
| Method | Use for | Limit |
|---|---|---|
typeof | Type primitive | No discrimination object/array/function |
instanceof | Specific Object | Can not use with primitive |
.constructor | Define class | It is not safe for the object to be changed by the prototype chain. |
Ví dụ:
[] instanceof Array // true
({}) instanceof Object // true
({}).constructor === Object // true8. JSON
JSON.stringify(undefined) // undefined
JSON.stringify({ a: undefined }) // "{}"
JSON.stringify([undefined]) // "[null]"Note: undefined can not be stringify → lead to lost data in POST API9. When do we need typeof, when not?
- Use
typeoffor primitive (number,string,boolean, etc.) - Use
Array.isArray()for array - Avoid
typeof null,typeof [],typeof NaN - Use
== nullto catchnullandundefined - Use
===to avoid coercion
10. Conclude
JavaScript is not a “strictly typed” language, but it is extremely easy to crash Gmail due to additional type coercion. Identifying intrinsic types, type limits, ==, ===, null, undefined will help you:
- Avoid hard-to-debug bugs
- Write clear, easy-to-maintain code
- Reduce QA time to fix "trivial" errors
Be skeptical of all comparisons in JavaScript. If you don't control the type, the type controls you..
Thanks for reading!