𝗪𝗵𝘆 𝘁𝘆𝗽𝗲𝗼𝗳 𝗻𝘂𝗹𝗹 𝗶𝘀 "𝗼𝗯𝗷𝗲𝗰𝘁" — 𝗧𝗵𝗲 𝟯𝟬-𝗬𝗲𝗮𝗿 𝗕𝘂𝗴 𝗧𝗵𝗮𝘁 𝗪𝗼𝗻’𝘁 𝗗𝗶𝗲 🐛 If you’ve ever debugged JavaScript and seen typeof null === 'object', you probably thought your code was broken. It’s not you. It’s one of the oldest "mistakes" in web history. Here’s the deep dive into why this quirk exists and why we’re stuck with it forever: 𝟭. 𝗧𝗵𝗲 "𝟭𝟬-𝗗𝗮𝘆" 𝗢𝗿𝗶𝗴𝗶𝗻 𝗦𝘁𝗼𝗿𝘆 ⏱️ In 1995, Brendan Eich created JavaScript in just 10 days. In that rush, the engine's internal structure used a "type tag" system to identify data. ● 𝗢𝗯𝗷𝗲𝗰𝘁𝘀 were assigned the tag 000. ● 𝗻𝘂𝗹𝗹, representing a null pointer, was represented as all zeros (0x00). Because the engine checked for the 000 tag to identify objects, and null consists entirely of zero bits, the typeof operator incorrectly flagged it as an object. 𝟮. 𝗧𝗵𝗲 𝗔𝘁𝘁𝗲𝗺𝗽𝘁𝗲𝗱 𝗙𝗶𝘅 🛠️ There was actually a proposal to "fix" this in ECMAScript 6 so that typeof null would return 'null'. So, why didn't it happen? 𝟯. 𝗧𝗵𝗲 "𝗗𝗼𝗻'𝘁 𝗕𝗿𝗲𝗮𝗸 𝘁𝗵𝗲 𝗜𝗻𝘁𝗲𝗿𝗻𝗲𝘁" 𝗥𝘂𝗹𝗲 🌐 Backward compatibility is the golden rule of the web. Millions of websites and legacy libraries rely on this specific bug for their logic. Changing it now would "break the internet," causing countless sites to crash. As Brendan Eich himself noted: “𝘐𝘵’𝘴 𝘵𝘰𝘰 𝘭𝘢𝘵𝘦 𝘵𝘰 𝘧𝘪𝘹.” 𝗧𝗵𝗲 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆 𝗳𝗼𝗿 𝗗𝗲𝘃𝘀: ✅ Never use typeof to check for null. ✅ Always use strict equality: myVar === null. ✅ Pro Tip: To check if something is actually a valid object, use: myVar !== null && typeof myVar === 'object'. JavaScript isn’t perfect, but its quirks are what make its history so fascinating. What’s your "favorite" JavaScript bug or quirk? Let’s discuss in the comments! 👇 #JavaScript #WebDevelopment #Programming #SoftwareEngineering #CodingLife #TechHistory #Frontend
JavaScript's
More Relevant Posts
-
𝙩𝙮𝙥𝙚𝙤𝙛 𝙣𝙪𝙡𝙡 === '𝙤𝙗𝙟𝙚𝙘𝙩' 𝙞𝙨 𝙤𝙣𝙚 𝙤𝙛 𝙅𝙖𝙫𝙖𝙎𝙘𝙧𝙞𝙥𝙩'𝙨 𝙢𝙤𝙨𝙩 𝙛𝙖𝙢𝙤𝙪𝙨 𝙡𝙞𝙚𝙨. And it's not a bug that slipped through, it's a 30-year-old fossil that the web is too fragile to remove. 𝙃𝙚𝙧𝙚'𝙨 𝙩𝙝𝙚 𝙧𝙚𝙖𝙡 𝙨𝙩𝙤𝙧𝙮 👇 𝗜𝘁 𝘀𝘁𝗮𝗿𝘁𝘀 𝗶𝗻 𝟭𝟵𝟵𝟱. 𝘉𝘳𝘦𝘯𝘥𝘢𝘯 𝘌𝘪𝘤𝘩 built JavaScript in 10 days. The original engine stored every value as a 32-bit word, with the lower bits acting as a "𝘵𝘺𝘱𝘦 𝘵𝘢𝘨" to tell the engine what kind of value it was dealing with. The tag for objects? 000. 𝗡𝗼𝘄 𝗵𝗲𝗿𝗲'𝘀 𝘄𝗵𝗲𝗿𝗲 𝗶𝘁 𝗴𝗼𝗲𝘀 𝘄𝗿𝗼𝗻𝗴. 𝘯𝘶𝘭𝘭 was represented as a null pointer. literally all zeros in memory: 0x00000000. When typeof read the lower bits of null, it saw... 000. The same bits that meant "𝘰𝘣𝘫𝘦𝘤𝘵." So it returned '𝘰𝘣𝘫𝘦𝘤𝘵'. And nobody caught it before it shipped. 𝗧𝗵𝗲 𝗳𝗶𝘅 𝘄𝗮𝘀 𝗽𝗿𝗼𝗽𝗼𝘀𝗲𝗱. 𝗧𝗵𝗲𝗻 𝗿𝗲𝗷𝗲𝗰𝘁𝗲𝗱. In 2006, the ECMAScript committee tried to fix it. typeof null would finally return '𝘯𝘶𝘭𝘭'. Makes total sense. But by then, millions of websites had already shipped code that accidentally relied on 𝘵𝘺𝘱𝘦𝘰𝘧 𝘯𝘶𝘭𝘭 === '𝘰𝘣𝘫𝘦𝘤𝘵'. Changing it would've broken the web. So the bug stayed. 𝘉𝘳𝘦𝘯𝘥𝘢𝘯 𝘌𝘪𝘤𝘩 himself has called it a mistake. 𝗧𝗵𝗲 𝗱𝗲𝗲𝗽𝗲𝗿 𝘁𝗮𝗸𝗲𝗮𝘄𝗮𝘆: Every language has fossils like this. Decisions made under pressure, in 10 days, that the entire ecosystem quietly built on top of. The next time you write val !== null && typeof val === 'object', you're not just being defensive. You're working around a 30-year negotiation between perfection and backwards compatibility. That's not a JavaScript quirk. 𝗧𝗵𝗮𝘁'𝘀 𝗲𝗻𝗴𝗶𝗻𝗲𝗲𝗿𝗶𝗻𝗴. 💬 𝘞𝘩𝘢𝘵'𝘴 𝘺𝘰𝘶𝘳 𝘧𝘢𝘷𝘰𝘶𝘳𝘪𝘵𝘦 𝘑𝘚 𝘲𝘶𝘪𝘳𝘬? 𝘋𝘳𝘰𝘱 𝘪𝘵 𝘣𝘦𝘭𝘰𝘸 #JavaScript #WebDevelopment #Programming #Frontend #TIL #SoftwareEngineering #React #TypeScript
To view or add a comment, sign in
-
-
If JavaScript is single‑threaded, how does it still handle Promises, API calls, and Timers without blocking the application? The answer lies in the Event Loop. Let’s take a simple example: What would be the output of the below code? console.log("Start"); setTimeout(() => { console.log("Timeout"); }, 0); Promise.resolve().then(() => { console.log("Promise"); }); console.log("End"); Some may guess the output to be: Start End Timeout Promise But the actual output is: Start End Promise Timeout So what is happening behind the scenes? 🔵 Synchronous Code Being synchronous, console.log("Start") and console.log("End") run immediately in the Call Stack. 🔵 Promises Resolved promises go to the Microtask Queue which is executed next. 🔵 setTimeout Timer callbacks go to the Macrotask Queue, even if the delay is '0ms', which is executed last. ✅ Simple flow to remember Synchronous Code → Promises (Microtasks) → setTimeout (Macrotasks) So even with 0 delay, Promises will always execute before setTimeout. Understanding this small but important detail will help developers debug async behavior and write more predictable JavaScript applications. #javascript #webdevelopment #eventloop #asyncprogramming
To view or add a comment, sign in
-
🚨 A small JavaScript behavior wasted 30 minutes of my debugging time today. I was extracting payment_ids from an array and wrote this: let paymentIds = filterArray ?.map(item => item.payment_id) .filter(item => item != null) .join(","); if (paymentIds.length > 0) { // run logic } And the condition paymentIds.length > 0 was always true. At first, I thought this was a bug in my code. But it turns out that JavaScript works this way. filterArray = [{id:1},{id:2},{id:3}] If the objects don’t contain payment_id, this happens: [undefined, undefined, undefined] and paymentIds outputs ",,,," So the string still has a length greater than 0, even though there are no real values. So, the correct approach is let paymentIds=filterArray ?.map(i => i.payment_id) .filter(Boolean) .join(","); Lesson learned When working with arrays in JavaScript: 👉 map() doesn't remove invalid values. 👉 join() will still create separators for undefined items. 👉 Checking string length alone can be misleading. Sometimes the smallest behaviors cause the biggest debugging sessions. #javascript #webdevelopment #frontend #reactjs #softwareengineering #codingtips
To view or add a comment, sign in
-
💡 JavaScript Tip: || vs ?? Many developers use || to set default values in JavaScript. But this can silently introduce bugs. Example: console.log(false || "temp"); // "temp" console.log(null || "temp"); // "temp" console.log(undefined || "temp"); // "temp" Why? Because || treats ANY falsy value as missing: false, 0, "", null, undefined, NaN Now look at the Nullish Coalescing operator (??): console.log(null ?? "temp"); // "temp" console.log(undefined ?? "temp"); // "temp" console.log(false ?? "temp"); // false ?? only replaces: null and undefined. Real example: let count = 0; console.log(count || 10); // 10 ❌ console.log(count ?? 10); // 0 ✅ ✔ Use || when you want to replace all falsy values ✔ Use ?? when you only want to replace null or undefined Small operator — but it can prevent real bugs in production. Do you usually use || or ?? for defaults? 🤔 #JavaScript #WebDevelopment #Frontend #Programming #SoftwareDevelopment
To view or add a comment, sign in
-
-
One of my favorite JavaScript one-liners: .filter(Boolean) Filtering out falsy values from an array meant chaining conditions and hoping I hadn't missed an edge case. When you pass Boolean as a callback to .filter(), JavaScript calls Boolean(item) on every element. Anything falsy - null, undefined, 0, "", false, NaN - gets removed. What you're left with is a clean array of only meaningful values. It's not just about writing less code. It's about communicating intent clearly. This pattern shines especially in real-world scenarios: cleaning up API responses, processing user input, or combining .map() and .filter() to transform and sanitize data in a single chain. #JavaScript #WebDevelopment #SoftwareEngineering #CleanCode #Frontend #Programming #JS #CodeQuality #TechTips #Developer --- I post about web engineering, front-end and soft skills in development. Follow me here: Irene Tomaini
To view or add a comment, sign in
-
-
You say you’re “comfortable with JavaScript”? Cool. Let’s test that. Answer these in the comments 👇 🧠 1. What will this output? Why? 𝘤𝘰𝘯𝘴𝘰𝘭𝘦.𝘭𝘰𝘨([] + []); 𝘤𝘰𝘯𝘴𝘰𝘭𝘦.𝘭𝘰𝘨([] + {}); 𝘤𝘰𝘯𝘴𝘰𝘭𝘦.𝘭𝘰𝘨({} + []); Most developers get at least one wrong. ⚡ 2. Predict the output: 𝘧𝘶𝘯𝘤𝘵𝘪𝘰𝘯 𝘰𝘶𝘵𝘦𝘳() { 𝘭𝘦𝘵 𝘤𝘰𝘶𝘯𝘵 = 0; 𝘳𝘦𝘵𝘶𝘳𝘯 𝘧𝘶𝘯𝘤𝘵𝘪𝘰𝘯 𝘪𝘯𝘯𝘦𝘳() { 𝘤𝘰𝘶𝘯𝘵++; 𝘤𝘰𝘯𝘴𝘰𝘭𝘦.𝘭𝘰𝘨(𝘤𝘰𝘶𝘯𝘵); }; } 𝘤𝘰𝘯𝘴𝘵 𝘧𝘯 = 𝘰𝘶𝘵𝘦𝘳(); 𝘧𝘯(); 𝘧𝘯(); 𝘧𝘯(); What concept is this testing? 🔥 3. What’s the difference between these two? 𝘖𝘣𝘫𝘦𝘤𝘵.𝘧𝘳𝘦𝘦𝘻𝘦(𝘰𝘣𝘫); 𝘖𝘣𝘫𝘦𝘤𝘵.𝘴𝘦𝘢𝘭(𝘰𝘣𝘫); When would you use one over the other in production? 🧩 4. True or False? 𝘵𝘺𝘱𝘦𝘰𝘧 𝘯𝘶𝘭𝘭 === "𝘰𝘣𝘫𝘦𝘤𝘵" 𝘐𝘧 𝘵𝘳𝘶𝘦 — 𝘦𝘹𝘱𝘭𝘢𝘪𝘯 𝘸𝘩𝘺. 𝘐𝘧 𝘧𝘢𝘭𝘴𝘦 — 𝘦𝘹𝘱𝘭𝘢𝘪𝘯 𝘸𝘩𝘺. 🚀 5. Async trap — what happens here? 𝘢𝘴𝘺𝘯𝘤 𝘧𝘶𝘯𝘤𝘵𝘪𝘰𝘯 𝘵𝘦𝘴𝘵() { 𝘳𝘦𝘵𝘶𝘳𝘯 42; } 𝘤𝘰𝘯𝘴𝘰𝘭𝘦.𝘭𝘰𝘨(𝘵𝘦𝘴𝘵()); What exactly gets logged? If you can answer all 5 confidently, you’re not just “using” JavaScript. You understand it. Drop your answers below 👇 Let’s see who’s interview-ready. #javascript #frontenddeveloper #codinginterview #webdevelopment #softwareengineering #DAY73
To view or add a comment, sign in
-
🚨 JavaScript Hoisting – Something Most Developers Still Misunderstand Most developers say: 👉 “JavaScript moves variables to the top of the scope.” But that’s not actually what happens. Let’s test this 👇 console.log(a); var a = 10; Output: undefined Now try this: console.log(b); let b = 20; Output: ReferenceError: Cannot access 'b' before initialization 💡 Why the difference? Both var and let are hoisted. But the real difference is initialization timing. ✔ var is hoisted and initialized with undefined during the creation phase. ✔ let and const are hoisted but stay inside the Temporal Dead Zone (TDZ) until the line where they are declared. That’s why accessing them before declaration throws an error. 👉 So technically: JavaScript doesn’t “move variables to the top”. Instead, the JavaScript engine allocates memory for declarations during the creation phase of the execution context. Small detail. But it explains a lot of confusing bugs. 🔥 Understanding this deeply helps when debugging closures, scope issues, and async code. #javascript #frontend #webdevelopment #reactjs #coding #softwareengineering
To view or add a comment, sign in
-
Don't do JavaScript. I mean it. The browser is a highly optimized engine written in C++, Rust, and C. It parses HTML. It diffs the DOM. It handles routing, focus, accessibility, scroll, history. It compresses repeated patterns with Brotli by factors of thousands. It is insanely good at this. And we keep replacing it. With JavaScript. ◆ How we got here Servers used to be slow. Threading was expensive. So we pushed logic to the client. SPAs made sense — in 2010. That constraint is gone. The complexity stayed. And quietly, over years, frameworks started re-implementing the browser itself. Virtual DOM. Client router. Hydration. State machines. JSON APIs just to feed them. We're not solving data problems anymore. We're solving framework problems. ◆ The forgotten principle: Progressive Enhancement Start with HTML that works. Always. No JavaScript required. Then layer interactivity on top — not as a dependency, but as an improvement. A page that works without JS and flies with it. That's not a compromise. That's good engineering. ◆ What the fast path actually looks like → Render HTML on the server — fully functional, accessible, indexable → Stream updates over a single SSE connection → Let the browser do diffing, layout, rendering → Repeated HTML over SSE + Brotli is often cheaper than your clever JSON diff → Add ~10 KB of Datastar for local state and reactivity on top → No build step — easier DevOps, faster iteration No virtual DOM. No hydration step. No client router. The server stays the source of truth. JS enhances — it doesn't own. ◆ Measure, don't vibe If one approach is 30–40x faster, uses less memory, less bandwidth, and less code — be willing to throw the old one away. The web was never slow. We just forgot how to use it. Delaney Gillilan explains this better than anyone — link in comments 👇 #JavaScript #ProgressiveEnhancement #WebDevelopment #Datastar #Hypermedia #SSE #CraftCMS
To view or add a comment, sign in
-
JavaScript Closures — made simple 💡 Closures sound complex… but they’re actually simple once you get the idea. A closure is when a function remembers variables from its outer scope even after the outer function has finished executing. Think of it like this: An inner function carries a “backpack” of variables and never forgets them. How it works: 1. Outer function creates a variable 2. Inner function uses that variable 3. Outer function returns the inner function 4. Inner function still has access to that variable Why closures are powerful: • Data privacy (encapsulation) • Maintain state between function calls • Used in callbacks, event handlers, React hooks • Foundation for advanced JavaScript concepts Real-world uses: • Counters • Private variables • One-time execution functions • Custom hooks & memoization One-line takeaway: A closure = function with a memory of its lexical scope If you understand closures, you’re moving from basics to real JavaScript thinking. What concept in JavaScript took you the longest to understand? #JavaScript #Closures #WebDevelopment #Frontend #CodingConcepts #LearnJavaScript #Programming #DeveloperLife
To view or add a comment, sign in
-
-
JavaScript Closures — made simple 💡 Closures sound complex… but they’re actually simple once you get the idea. A closure is when a function remembers variables from its outer scope even after the outer function has finished executing. Think of it like this: An inner function carries a “backpack” of variables and never forgets them. How it works: 1. Outer function creates a variable 2. Inner function uses that variable 3. Outer function returns the inner function 4. Inner function still has access to that variable Why closures are powerful: • Data privacy (encapsulation) • Maintain state between function calls • Used in callbacks, event handlers, React hooks • Foundation for advanced JavaScript concepts Real-world uses: • Counters • Private variables • One-time execution functions • Custom hooks & memoization One-line takeaway: A closure = function with a memory of its lexical scope If you understand closures, you’re moving from basics to real JavaScript thinking. What concept in JavaScript took you the longest to understand? #JavaScript #Closures #WebDevelopment #Frontend #CodingConcepts #LearnJavaScript #Programming #DeveloperLife
To view or add a comment, sign in
-