Look Inside Yourself: Reflection and Introspection in JavaScript

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

What are Reflection and Introspection in JavaScript and Why Do You Need Them?

\n\n

Imagine you are a programmer-detective. You have an object, but you don't know what's inside it. What properties does it have? What is its nature — an array, a function, or just a set of data? In everyday life, we just look at the code, but in the dynamic world of JavaScript, your program must be able to do this itself. This is reflection and introspection.

\n\n

These terms sound like philosophy, but in reality, they are powerful tools. Introspection is when code looks at itself: it checks the type of a variable, finds out the name of a function, or enumerates the properties of an object. Reflection goes further — it is the ability of code to modify itself during execution: adding new methods, changing prototypes, or even creating proxy objects.

\n\n

At first glance, it might seem that this is only needed by authors of complex frameworks. But in fact, every day you use introspection without even noticing it. When you write typeof x === 'string' — you are already doing introspection. And when you use Object.assign to copy properties — you are applying reflection.

\n\n

In this article, we will break down all the key methods and techniques. You will learn how to "look inside" any object, how to safely work with unknown data, and how to write more flexible and adaptive code. Let's go!

\n\n

Basics of Introspection: Looking at What We Have in Our Hands

\n\n

Introspection starts with a simple question: "What is this?". JavaScript has several built-in operators and methods that help answer this question.

\n\n

The typeof Operator: Quick Type Check

\n\n

This is your first helper. typeof returns a string indicating the type of the operand. It's simple, but it has a couple of pitfalls.

\n\n
console.log(typeof 42);        // "number"\nconsole.log(typeof 'hello');   // "string"\nconsole.log(typeof true);      // "boolean"\nconsole.log(typeof undefined); // "undefined"\nconsole.log(typeof null);      // "object" — here it is, the famous bug!\nconsole.log(typeof []);        // "object" — and this is not a bug, but a feature\nconsole.log(typeof function(){}); // "function"
\n\n

Note: typeof null returns "object". This is a historical error in JavaScript that won't be fixed. typeof [] also returns "object", which is logical since an array is a subtype of an object. But how then to distinguish an array from a regular object? There are other tools for that.

\n\n

Useful tip: typeof is perfect for checking if a variable is defined, without the risk of throwing a ReferenceError exception.

\n\n
if (typeof someGlobalVar !== 'undefined') {\n  // Safely use someGlobalVar\n}
\n\n

instanceof: Checking the Prototype Chain

\n\n

If typeof answers the question "what primitive type?", then instanceof answers "is it an object of a certain class?". It checks whether the constructor's prototype is present in the object's prototype chain.

\n\n
const arr = [1, 2, 3];\nconsole.log(arr instanceof Array);  // true\nconsole.log(arr instanceof Object); // true — because Array inherits from Object\n\nconst date = new Date();\nconsole.log(date instanceof Date);   // true\nconsole.log(date instanceof Object); // true\n\n// But it doesn't work with primitives\nconsole.log('hello' instanceof String); // false — primitive is not an object
\n\n

Important nuance: instanceof can fail when working with iframes or different execution contexts (e.g., in Node.js). Each context has its own global object, and [] instanceof window.Array might return false if the array was created in a different frame. For such cases, it's better to use Array.isArray().

\n\n

Array.isArray() and Object.prototype.toString

Blogs

Book Recommendations