<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="vi"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://duclvz.github.io/en/feed.xml" rel="self" type="application/atom+xml" /><link href="https://duclvz.github.io/en/" rel="alternate" type="text/html" hreflang="vi" /><updated>2026-05-09T03:45:53+00:00</updated><id>https://duclvz.github.io/feed.xml</id><title type="html">DUCLVZ</title><subtitle>duclvz&apos;s blog</subtitle><author><name>Duc Lv</name></author><entry xml:lang="en"><title type="html">Where Hallucination Really Comes From</title><link href="https://duclvz.github.io/en/posts/where-hallucination-really-comes-from" rel="alternate" type="text/html" title="Where Hallucination Really Comes From" /><published>2026-05-03T20:00:00+00:00</published><updated>2026-05-03T20:00:00+00:00</updated><id>https://duclvz.github.io/posts/where-hallucination-really-comes-from</id><content type="html" xml:base="https://duclvz.github.io/posts/where-hallucination-really-comes-from"><![CDATA[<p>There’s a common story about AI hallucination: it’s mostly a prompting problem. Give the model better context, the made-up facts go away. It’s a comforting story — tweak the prompt, fix the output, stay in control. The reality is messier. Hallucination has layers, and context is just the top one.</p>

<h2 id="context-matters-but-its-not-the-whole-picture">Context matters, but it’s not the whole picture</h2>

<p>Bad context absolutely causes hallucination. When your prompt is vague, too long, full of noise, or carries wrong assumptions from the start, the model latches onto the wrong signals. It fills gaps with plausible-sounding nonsense because that’s what it’s optimized to do — produce coherent text, not verified truth.</p>

<p>Ask “compare it to the older version” without saying what “it” is, and the model will guess. Sometimes it guesses right. Sometimes it confidently describes a comparison between two things that never existed. Stuff too many documents into a limited context window and the model drops important bits or stitches together fragments that don’t belong together — the output sounds coherent, the facts are wrong.</p>

<p>Context hygiene matters. But even with a perfectly crafted prompt, hallucination still happens, because the problem goes deeper than prompts.</p>

<h2 id="the-three-layers-of-hallucination">The three layers of hallucination</h2>

<p><strong>Layer 1: Prompt and context.</strong> This is the one everyone talks about. Vague instructions, conflicting information, missing constraints. Fixable: write clearer prompts, remove noise, be specific about what you want and what you don’t want.</p>

<p><strong>Layer 2: The model itself.</strong> This is the uncomfortable one. LLMs don’t look up facts in a database. They predict the next most probable token given the current context. The whole training objective is “produce text that looks right” — not “produce text that is right.” A fluent, confident answer and a factually correct answer aren’t the same thing, and the model is optimized for the first.</p>

<p>On top of that, LLMs are stateless. Every request, the model only sees the tokens you send in that exact request. Want it to remember earlier conversation? You resend the whole history. Anything that’s missing, it guesses, and guesses compound. Context windows are finite too — once the problem gets complex enough, something has to drop, and the model doesn’t tell you what it forgot. It just keeps going, stitching reasoning from whatever fragments remain. Research backs this up: longer context often means worse reasoning.</p>

<p><strong>Layer 3: Training data and external knowledge.</strong> This is the foundation. Training data that’s incomplete, biased, or flat-out wrong means the model learned incorrect correlations from day one. Outdated knowledge means it confidently answers questions about events that happened after its training cutoff. Overfitting means it memorized patterns that don’t generalize — give it a slightly different input and reasoning drifts. Knowledge in an LLM is compressed into weights, not anchored to specific sources: the model “knows” something but has no idea where it came from. And it’s wired to always answer, never say “I don’t know” — so when there’s a gap, it fills it with something that sounds reasonable.</p>

<h2 id="what-this-means-in-practice">What this means in practice</h2>

<p>I’ve stopped asking “is this hallucination?” and started asking “which layer did this come from?”</p>

<p>When Claude Code confidently invents a function that doesn’t exist in the codebase, that’s usually Layer 1 — not enough context about what’s actually in the project. When it gives a perfectly reasonable-sounding explanation for a bug that’s completely wrong, that’s often Layer 2 — the model constructed a coherent narrative from probabilistic token selection, not from understanding the actual runtime state. When it cites a library feature that doesn’t exist or an API deprecated two years ago, that’s Layer 3 — a training-data issue or outdated knowledge.</p>

<p>Knowing which layer is at play changes the response. Layer 1 problems are fixed by improving the prompt. Layer 2 problems are caught by reading every line of generated code and asking “why” instead of just “how.” Layer 3 problems are solved by feeding the model relevant documentation in the context — RAG, effectively — instead of trusting its built-in knowledge.</p>

<h2 id="what-actually-helps">What actually helps</h2>

<p>Nothing eliminates hallucination entirely, but a few practices meaningfully reduce it:</p>

<ul>
  <li>Be specific in prompts. Name the entities, timeframe, scope, criteria. “Write a function” is a hallucination invitation. “Write a TypeScript function that validates email format using RFC 5322, returning <code class="language-plaintext highlighter-rouge">{ valid: boolean, reason?: string }</code>” is much safer.</li>
  <li>Keep context lean but sufficient. Remove noise, contradictions, approaches you already decided against. Every extra piece of information is another chance for the model to get confused about what matters.</li>
  <li>For anything requiring factual accuracy or recent data, feed the sources directly into the context. Don’t ask the model what it “knows” — it doesn’t know, it predicts. Give it the documents and tell it to answer from those documents only.</li>
  <li>Ask for sources and reasoning chains — not because the model can verify truth (it can’t), but because seeing its reasoning makes it easier to spot where it went wrong. A hallucination with a visible reasoning chain is a bug you can debug. A hallucination with no reasoning is just a claim you might believe.</li>
  <li>Read the output. All of it. The easiest step to skip, and the most important.</li>
</ul>

<h2 id="the-bottom-line">The bottom line</h2>

<p>“Hallucination is just bad context” is a comforting story — it implies complete control if we just write better prompts. The less comfortable truth is that hallucination is built into how LLMs work. Next-token prediction produces text that looks right, not text that is right. Training data has gaps and biases. Knowledge goes stale. The model can’t verify facts, and won’t say “I don’t know” on its own. Better prompts help, better architecture helps, RAG helps. But the real skill isn’t preventing hallucination — it’s the habit of verifying everything, even when the answer sounds perfect. The hallucinations that bite hardest aren’t the ones that look wrong — they’re the ones that look right.</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="ai" /><category term="llm" /><category term="hallucination" /><category term="technical" /><summary type="html"><![CDATA[Bad context makes hallucination worse, but even perfect context won't stop it. The real causes run deeper — and knowing them changes how you use AI.]]></summary></entry><entry xml:lang="en"><title type="html">AI Is Not Magic</title><link href="https://duclvz.github.io/en/posts/ai-is-not-magic" rel="alternate" type="text/html" title="AI Is Not Magic" /><published>2026-04-30T20:00:00+00:00</published><updated>2026-04-30T20:00:00+00:00</updated><id>https://duclvz.github.io/posts/ai-is-not-magic</id><content type="html" xml:base="https://duclvz.github.io/posts/ai-is-not-magic"><![CDATA[<p>Every platform right now is pushing the same line: adopt AI or get left behind. Small teams replacing whole departments, solo founders shipping products in a weekend, job titles nobody had heard of six months ago suddenly labeled “the next big thing.” Look past the hype at how people actually use these tools day to day and the picture is messier. A small group has genuinely reshaped their workflow. Most land somewhere between underwhelmed and quietly giving up. The gap between the marketing and what’s happening on the ground is the interesting part.</p>

<h2 id="everybody-says-ai-but-nobody-means-the-same-thing">Everybody says “AI”, but nobody means the same thing</h2>

<p>I was grabbing coffee with a founder a while back. He was pumped: “We’re integrating AI into our product, what do you think?”</p>

<p>I asked: “What kind of AI? LLM chat? Agentic? Automation?”</p>

<p>He paused, then laughed: “I mean… you know, AI. The AI thing.”</p>

<p>That’s where it starts. Most people lump it all into one word. LLM? AI. Chatbot? AI. Automation tool? AI. Copilot? AI. But Claude Code, ChatGPT, Cursor, Copilot are wildly different tools. Using the wrong one for a task is like grabbing a screwdriver to hammer a nail. When you can’t tell what you’re holding, you either expect too much or get frustrated and bail. Neither ends well.</p>

<h2 id="what-its-good-at-what-it-sucks-at">What it’s good at, what it sucks at</h2>

<p>From what I’ve seen across teams and projects, AI coding tools genuinely boost productivity — but only for certain kinds of work.</p>

<p>Stuff with clear templates and well-worn patterns: writing tests, generating boilerplate, refactoring known structures, docs. The speed difference is dramatic. Work that used to eat half a day wraps up in under ten minutes.</p>

<p>Holistic, multi-dimensional reasoning is a different story — system architecture, tech stack choices for a specific problem, weighing performance against maintainability. A few technical constraints explain why.</p>

<p>LLM APIs are stateless. Each request, the model only sees the tokens in that request. Want it to remember the earlier chat? You resend the whole history every turn. Context is thin, it has to guess, and guesses go wrong.</p>

<p>Context windows are finite. Overflow the window and the model silently drops things, stitching reasoning from whatever’s left. Research has consistently shown that longer contexts tend to degrade reasoning rather than improve it.</p>

<p>And there’s information poisoning. Feed the model five different approaches to the same problem and it has to reason through which one applies. More reasoning steps, higher cumulative error.</p>

<p>You see the pattern everywhere: someone types “build me an e-commerce site like Shopify” and waits. Ten minutes in, the AI starts drifting, hallucinating. They get frustrated and write the whole thing off. But the AI never had a real sense of what they wanted — it was doing its best with a three-line prompt.</p>

<h2 id="builders-and-architects">Builders and Architects</h2>

<p>There’s a metaphor that shows up in engineering discussions: builders versus architects.</p>

<p>Builders do repetitive work with clear processes — mix mortar, lay bricks, plaster walls. AI is great at this kind of work. Fast, clean, few careless mistakes.</p>

<p>Architects put together the master plan, balancing aesthetics, function, structure, cost. They define the framework the builders follow.</p>

<p>AI is a superhuman builder. The architect has to be you.</p>

<p>Here’s the part worth internalizing: AI works best when you’ve already thought the problem through. Sketch the architecture, hand it over, and it helps you build faster. Hand it an empty lot and say “build me a house” — you’ll get something, but it might be a chicken coop. The best prompts consistently come after the thinking, not before.</p>

<p>Applied to software: if your job is mostly writing repetitive, pattern-based code, AI is a real competitive threat. It’s faster and cleaner. But if you’re a Solution Architect or Business Analyst — analyzing the big picture, understanding the problem, designing solutions — AI is an ally, not a replacement.</p>

<h2 id="how-to-use-it-well">How to use it well</h2>

<p>Before opening the AI, sit with the problem for at least ten minutes. Sounds simple. On tired days the temptation to skip that step is real. A good prompt comes from knowing what you don’t know — not from being in a hurry.</p>

<p>Ask “why,” not just “how.” The AI suggests a solution — make it explain. Why this approach? What else did it consider? What’s the trade-off? If it can’t explain convincingly, it doesn’t get merged.</p>

<p>Read every line of generated code. Plenty of people see “it runs” and move on, but that’s how bugs you don’t understand end up in production. If you don’t understand what the AI wrote, you’ll be back asking it again in the same loop.</p>

<p>And once a week, do a no-AI session. Turn everything off — editor and docs. First time feels like withdrawal. After a few weeks the difference in debugging speed and clarity of thought is noticeable. Think of it as maintenance for your own reasoning.</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="ai" /><category term="mindset" /><category term="productivity" /><category term="career" /><summary type="html"><![CDATA[Social media is selling a dream: just use AI and you'll succeed. But in reality, very few people achieve real results. Why?]]></summary></entry><entry xml:lang="en"><title type="html">Don’t Let AI Think For You</title><link href="https://duclvz.github.io/en/posts/dont-let-ai-think-for-you" rel="alternate" type="text/html" title="Don’t Let AI Think For You" /><published>2026-04-29T20:00:00+00:00</published><updated>2026-04-29T20:00:00+00:00</updated><id>https://duclvz.github.io/posts/dont-let-ai-think-for-you</id><content type="html" xml:base="https://duclvz.github.io/posts/dont-let-ai-think-for-you"><![CDATA[<p>There’s a loop I keep falling into with AI coding tools: hit a bug, paste the code, get a confident fix, apply it, move on. Five minutes. Feels efficient. Then the next day the bug comes back, and I realize nobody — me or the AI — ever understood it.</p>

<p>A React state bug caught me in this loop recently. State updating wrong, UI rendering all over the place. Claude Code gave me a confident explanation and a fix. Applied it, ran it, worked. Closed the tab.</p>

<p>Next day, bug’s back. This time I turned the AI off, traced every state transition by hand, re-read the <code class="language-plaintext highlighter-rouge">useEffect</code> cleanup. Took almost an hour. The real cause was a wrong assumption about timing — something Claude Code had no way of knowing, because it doesn’t actually understand the codebase. It answers the question you asked. And I’d asked the wrong one.</p>

<p>That’s the part I keep missing. The AI didn’t give a wrong answer. It gave the right answer to a question I hadn’t thought through.</p>

<h2 id="what-slowly-slips-away">What slowly slips away</h2>

<p>Spend enough time with AI coding tools and something starts to shift. I <em>know</em> more. Whether I <em>understand</em> more, I’m less sure.</p>

<p>The answers aren’t just fast — they’re plausible enough that you stop pushing back, a little at a time. Your brain picks up a new default: see a problem, want an answer, skip the part where you sit with it. You stop being patient with the ambiguity and the hard bits. What worries me isn’t the hours of research I save. It’s that the muscle for building an argument from scratch quietly weakens, and you don’t notice until you need it.</p>

<p>I pair-programmed with a junior dev a while back. We hit a query optimization thing and their hand went straight to Cursor. I said, “Hold on. Turn it off. What would you do without AI?” They sat there for five minutes and then: “I don’t know where to start.” The problem wasn’t hard. But “ask AI first, think later” had already become reflex. That’s the habit a lot of new devs are forming right now.</p>

<h2 id="why-it-cant-think-for-you">Why it can’t think for you</h2>

<p>There are a few technical reasons the “let the AI figure it out” approach breaks down.</p>

<p>LLM APIs are stateless. Each request, the model only sees what’s in that request. Want it to remember the earlier conversation? You resend the whole thing. Anything missing, it guesses, and guesses compound.</p>

<p>Context windows are finite. Once a problem gets complex enough to overflow the window, the model silently drops things and reasons from whatever’s left. Plenty of research shows longer contexts actually degrade reasoning quality.</p>

<p>And there’s information poisoning. Same problem, five different solutions floating in the context — now the model has to pick, and every extra reasoning step is another chance to drift.</p>

<p>The short version: if you haven’t thought the problem through, there’s no way for the AI to think it through for you.</p>

<h2 id="first-brain-and-second-brain">First Brain and Second Brain</h2>

<p>People talk a lot about building a “Second Brain” with AI — memory, knowledge graphs, prompt libraries, rule engines. The tooling really is powerful. I use some of it.</p>

<p>But it only helps if your First Brain still works — sharp enough to verify, to doubt, to catch contradictions, to make the final call. I’ve watched people pour everything into a Second Brain while their First Brain quietly atrophies. What you get isn’t competence. Just confusion, faster.</p>

<p>Early on, using AI coding tools felt like having a fast classmate next to me. Reads quick, writes quick, remembers a lot. Thirty seconds, ten proposals. But he doesn’t know my codebase, doesn’t know the project, and if production goes down at 2am it’s not his problem. He’s sharp. The question was always whether I was sharp enough to check his work. The days I was tired and handed everything off without checking were the same days bugs made it through.</p>

<h2 id="how-i-use-it-now">How I use it now</h2>

<p>Opening AI is the last step, not the first. I sit with the problem for at least ten minutes before touching the tool, even on tired days. Those ten minutes let me pinpoint what I actually don’t know, instead of a fuzzy “I don’t know anything,” and the prompt that follows is noticeably better.</p>

<p>I ask “why,” not just “how.” It suggests a solution, I push: why this, what else did you consider, what’s the trade-off? If it can’t explain convincingly, it doesn’t get merged.</p>

<p>I read every line of generated code. This is the easiest step to skip, and probably where most of the avoidable production bugs come from. Code that looks fine on a quick skim has a way of turning up later as the root cause.</p>

<p>And one no-AI session a week. Copilot off, Claude Code off, editor and docs. First time is uncomfortable. After a few weeks, though, debugging from first principles gets quicker and my own reasoning feels sharper. Think of it as maintenance for the part of the system that matters most.</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="ai" /><category term="coding" /><category term="productivity" /><category term="mindset" /><summary type="html"><![CDATA[AI coding agents help us code faster, but they also quietly take away our ability to think independently. How to use AI while keeping your First Brain sharp.]]></summary></entry><entry xml:lang="en"><title type="html">Memory Leaks in JavaScript</title><link href="https://duclvz.github.io/en/posts/memory-leaks-in-javascript" rel="alternate" type="text/html" title="Memory Leaks in JavaScript" /><published>2020-06-06T20:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://duclvz.github.io/posts/memory-leaks-in-javascript</id><content type="html" xml:base="https://duclvz.github.io/posts/memory-leaks-in-javascript"><![CDATA[<p>Memory leaks are a problem every developer eventually faces. Memory leaks cause applications to run slower, crash, or affect other applications. So what are memory leaks?</p>

<p>A memory leak can be defined as memory that is no longer used by the application but, for some reason, hasn’t been released back to the operating system or a pool of free memory. Different programming languages have different ways of managing memory. These memory management approaches help reduce the likelihood of memory leaks. However, determining whether a piece of memory is still in use is a difficult problem. Only the developer can truly decide whether that memory should be freed. Some languages (like JavaScript) provide automatic memory management for developers; others require developers to manually free memory when it’s no longer needed.</p>

<h3 id="memory-management-in-js">Memory management in JS</h3>

<p>JavaScript is one of the languages with <em>garbage collection</em>. Languages like JavaScript manage memory on behalf of the developer by periodically checking whether previously allocated memory can still be “reached” by other parts of the application. In other words, languages like JavaScript transform the problem from <em>“which memory is still needed by the application”</em> to <em>“which memory can still be accessed by the application.”</em> The difference between these two problems is subtle but crucial: only the developer knows what memory is still needed, but determining whether memory is reachable can be automated by an algorithm.</p>

<h2 id="memory-leaks-in-js">Memory leaks in JS</h2>

<p>The main cause of memory leaks in garbage-collected languages is unwanted references — memory that is referenced but not actually used by the application. To understand this better, we first need to understand how garbage collectors work and how they determine whether memory is “reachable.”</p>

<h3 id="mark-and-sweep">Mark and sweep</h3>

<p>Most garbage collectors use the <code class="language-plaintext highlighter-rouge">mark-and-sweep</code> algorithm to free memory. The algorithm consists of these steps:</p>

<ol>
  <li>First, the garbage collector builds a list of <code class="language-plaintext highlighter-rouge">roots</code>. <code class="language-plaintext highlighter-rouge">Roots</code> are essentially global variables whose references are stored in code. In JavaScript, <code class="language-plaintext highlighter-rouge">window</code> is such a global variable. <code class="language-plaintext highlighter-rouge">Window</code> always exists in the program, so the garbage collector considers it and all its children as always present.</li>
  <li>All <code class="language-plaintext highlighter-rouge">roots</code> and their children are marked as active. Any memory that can be reached from <code class="language-plaintext highlighter-rouge">roots</code> is considered active and not marked as garbage.</li>
  <li>All memory not marked as active is now considered garbage. The collector can then free this memory.</li>
</ol>

<p>Although modern GCs have optimized this algorithm, the mechanism remains unchanged: reachable memory is considered active; everything else is considered garbage.</p>

<p>Unwanted references are references to memory that the developer knows is no longer needed but, for some reason, is still retained in the system. In JS, these unwanted references are variables kept somewhere in code that will never be used again but still point to memory that should be freed.</p>

<h2 id="4-types-of-memory-leaks-in-js">4 types of memory leaks in JS</h2>

<h3 id="1-global-variables">1: Global variables</h3>

<p>JavaScript allows declaring variables without a declaration keyword. For example:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">a</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">value</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">a</span><span class="p">);</span> <span class="c1">// "a"</span>
</code></pre></div></div>

<p>When a variable is declared this way, JS automatically attaches it to the <code class="language-plaintext highlighter-rouge">global</code> object (<code class="language-plaintext highlighter-rouge">window</code> in browsers). If this variable only operates in global scope, there’s not much difference. But if it’s defined inside a function, that’s another story:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">foo</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">bar</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">this is an implicit global variable</span><span class="dl">'</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The above code is equivalent to this in the browser:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">foo</span><span class="p">()</span> <span class="p">{</span>
  <span class="nb">window</span><span class="p">.</span><span class="nx">bar</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">this is a global variable</span><span class="dl">'</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>If <code class="language-plaintext highlighter-rouge">bar</code> is declared within <code class="language-plaintext highlighter-rouge">foo</code>’s scope without using <code class="language-plaintext highlighter-rouge">var</code>, <code class="language-plaintext highlighter-rouge">bar</code> is created in global scope — a textbook example of a memory leak.</p>

<p>Another way to accidentally create global variables is through <code class="language-plaintext highlighter-rouge">this</code>:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">foo</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">variable</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">could be a global variable</span><span class="dl">'</span><span class="p">;</span>
<span class="p">}</span>

<span class="nf">foo</span><span class="p">();</span>
</code></pre></div></div>

<p>Since <code class="language-plaintext highlighter-rouge">this</code> in a function points to the global root (<code class="language-plaintext highlighter-rouge">window</code>) when the function is called directly (not through an object), in the example above, <code class="language-plaintext highlighter-rouge">variable</code> gets attached to global scope.</p>

<p>One way to mitigate these errors is to add <code class="language-plaintext highlighter-rouge">"use strict;"</code> at the top of your JS file. It prevents accidental global variable declarations like the above.</p>

<p><strong>Note when working with global variables</strong></p>

<p>Global variables are never automatically freed by the <code class="language-plaintext highlighter-rouge">mark-and-sweep</code> algorithm. Therefore, global variables should only be used to temporarily store data for processing. If you need to store a large amount of data in a global variable, make sure to set it to <code class="language-plaintext highlighter-rouge">null</code> or reassign it when you’re done.</p>

<h3 id="2-forgotten-callbacks-and-timers">2: Forgotten callbacks and timers</h3>

<p>Here’s an example of a memory leak with <code class="language-plaintext highlighter-rouge">setInterval</code>:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nf">getData</span><span class="p">();</span>
<span class="nf">setInterval</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
  <span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">Node</span><span class="dl">"</span><span class="p">);</span>
  <span class="k">if</span><span class="p">(</span><span class="nx">node</span><span class="p">){</span>
    <span class="nx">node</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">(</span><span class="nx">someResource</span><span class="p">));</span>
  <span class="p">}</span>
<span class="p">},</span> <span class="mi">1000</span><span class="p">);</span>
</code></pre></div></div>

<p>This is an example of a hanging timer. A hanging timer is one that references nodes or data that are no longer in use. In the example above, if <code class="language-plaintext highlighter-rouge">node</code> is removed at some point, the entire callback code in the interval is no longer needed. However, because the interval is still active, the memory used in the callback can’t be freed (you’d need to stop the interval first). Additionally, external objects referenced by the interval callback also can’t be freed because they remain reachable through that callback. In the example above, that’s <code class="language-plaintext highlighter-rouge">data</code>.</p>

<p>Another leak-prone case involves observer objects (DOM and their event listeners). This mainly affects older browsers (e.g., IE6) because modern browsers handle this automatically. This was a bug in IE6’s GC leading to circular references.</p>

<h3 id="3-references-to-detached-dom-nodes">3: References to detached DOM nodes</h3>

<p>Sometimes you want to store DOM nodes in data structures like arrays or objects in JS code to perform various operations. For example, if you want to update data in several elements, storing them in an array makes sense. When this happens, there are two references to that DOM element: one from the DOM tree, and one from the JS array object. If you want to remove these elements, you need to remove all references to them to free the memory.</p>

<p>Example:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">elements</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">button</span><span class="p">:</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">button</span><span class="dl">'</span><span class="p">),</span>
  <span class="na">image</span><span class="p">:</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">image</span><span class="dl">'</span><span class="p">),</span>
  <span class="na">text</span><span class="p">:</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">text</span><span class="dl">'</span><span class="p">),</span>
<span class="p">};</span>

<span class="kd">function</span> <span class="nf">doStuff</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">image</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">http://some.url/image</span><span class="dl">'</span><span class="p">;</span>
  <span class="nx">button</span><span class="p">.</span><span class="nf">click</span><span class="p">();</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">text</span><span class="p">.</span><span class="nx">innerHTML</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">removeButton</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// button is a child of body.</span>
  <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nf">removeChild</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">button</span><span class="dl">'</span><span class="p">));</span>

  <span class="c1">// Here, button is still referenced by elements. In other words,</span>
  <span class="c1">// it still resides in memory and cannot be freed.</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Another important issue is when you reference a leaf node or inner node of a DOM tree, such as a table cell (<code class="language-plaintext highlighter-rouge">&lt;td&gt;</code> of a <code class="language-plaintext highlighter-rouge">&lt;table&gt;</code>). If you keep a reference to that <code class="language-plaintext highlighter-rouge">&lt;td&gt;</code> in JS code, then when you remove the <code class="language-plaintext highlighter-rouge">&lt;table&gt;</code> containing it, the GC cannot free the entire table — not just that <code class="language-plaintext highlighter-rouge">&lt;td&gt;</code>. Because the child node still references its parent, the GC considers the parent referenced and skips it. So be careful when keeping references to DOM nodes.</p>

<h3 id="4-closures">4: Closures</h3>

<p>Closures simply mean a function inside another function’s scope that can reference variables from the outer function. Why can closures cause leaks? Look at this example:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">theThing</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">replaceThing</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">originalThing</span> <span class="o">=</span> <span class="nx">theThing</span><span class="p">;</span>
  <span class="kd">var</span> <span class="nx">unused</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="k">if </span><span class="p">(</span><span class="nx">originalThing</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi</span><span class="dl">'</span><span class="p">);</span>
  <span class="p">};</span>
  <span class="nx">theThing</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">longStr</span><span class="p">:</span> <span class="k">new</span> <span class="nc">Array</span><span class="p">(</span><span class="mi">1000000</span><span class="p">).</span><span class="nf">join</span><span class="p">(</span><span class="dl">'</span><span class="s1">*</span><span class="dl">'</span><span class="p">),</span>
    <span class="na">someMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">someMessage</span><span class="p">);</span>
    <span class="p">},</span>
  <span class="p">};</span>
<span class="p">};</span>
<span class="nf">setInterval</span><span class="p">(</span><span class="nx">replaceThing</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
</code></pre></div></div>

<p>This example shows that each time <code class="language-plaintext highlighter-rouge">replaceThing</code> is called, <code class="language-plaintext highlighter-rouge">theThing</code> creates a new object containing an array and a closure (<code class="language-plaintext highlighter-rouge">someMethod</code>). At the same time, the <code class="language-plaintext highlighter-rouge">unused</code> variable also holds a closure referencing <code class="language-plaintext highlighter-rouge">originalThing</code> (which is the <code class="language-plaintext highlighter-rouge">theThing</code> object created from the previous <code class="language-plaintext highlighter-rouge">replaceThing</code> call). Importantly, when a scope is created for closures sharing the same parent scope, they share that scope. In this example, <code class="language-plaintext highlighter-rouge">someMethod</code> and <code class="language-plaintext highlighter-rouge">unused</code> share the same scope. Even though <code class="language-plaintext highlighter-rouge">unused</code> is never called, because it references <code class="language-plaintext highlighter-rouge">originalThing</code>, the GC considers it still active. When this code runs, memory grows steadily and is immediately visible. Essentially, a linked list of closures is created (rooted at <code class="language-plaintext highlighter-rouge">theThing</code>), which is why memory increases over time.</p>

<h2 id="garbage-collectors">Garbage Collectors</h2>

<p>Although GCs save us from manual memory management, there are trade-offs. One is that GCs operate unpredictably. It’s usually hard to be certain whether a collection has occurred. This also means that in some cases, a program’s memory usage is higher than what it actually needs. In other cases, applications suffer from brief pauses while collection runs. Currently, most GCs only trigger collection during memory allocation. If no allocation happens, GCs remain idle. Consider these scenarios:</p>

<ol>
  <li>The program has allocated a small amount of memory.</li>
  <li>Later, most (or all) elements become unreachable.</li>
  <li>The program stops allocating memory.</li>
</ol>

<p>In this situation, most GCs will not run further collections. In other words, even though unreachable elements exist, they won’t be reclaimed. This isn’t strictly a leak, but it still causes memory bloat.</p>

<h2 id="chrome-memory-profiling-tools">Chrome Memory Profiling Tools</h2>

<p>Chrome provides a set of tools to inspect the memory usage of JS code. Two important views related to memory are: <em>timeline</em> and <em>profiles</em>.</p>

<h3 id="timeline-view">Timeline View</h3>

<p><code class="language-plaintext highlighter-rouge">Timeline View</code> helps us see the memory usage pattern of a program. From here, we can detect memory leaks — memory usage that continuously increases over time without decreasing after each GC run.</p>

<p><img src="https://cdn.auth0.com/blog/jsleaks/timeline.png" alt="timeline" /></p>

<p>We can see the memory leak through the JS heap steadily growing over time. Even after a large collection at the end, the program still uses more memory than at the start. The Node count is also higher — a sign of DOM nodes leaking somewhere in the code.</p>

<h3 id="profiles-view">Profiles view</h3>

<p><img src="https://cdn.auth0.com/blog/jsleaks/profiles.png" alt="profiles" /></p>

<p>This is the tool you’ll rely on when investigating memory leaks. <code class="language-plaintext highlighter-rouge">Profiles view</code> lets you take snapshots of a JavaScript program’s memory usage. It also lets you record memory allocations over time. Each result type provides different lists, but what you need to focus on are the summary list and the comparison list.</p>

<p><code class="language-plaintext highlighter-rouge">Summary View</code> gives an overview of object types created and allocated, along with aggregated sizes: Shallow size (total size of all objects of a specific type) and Retained size (shallow size plus the size of objects retained by this object). It also shows the distance between an object and the root.</p>

<p><code class="language-plaintext highlighter-rouge">Comparison View</code> provides the same information as <code class="language-plaintext highlighter-rouge">summary view</code> but allows comparison between different snapshots.</p>

<h2 id="example-finding-memory-leaks-in-chrome">Example: Finding memory leaks in Chrome</h2>

<p>There are two main types of memory leaks: leaks that cause memory to grow steadily over time, and leaks that happen once without causing further memory growth. Finding steadily-growing leaks is relatively straightforward (using <code class="language-plaintext highlighter-rouge">timeline view</code>). However, these are the most troublesome: if memory keeps growing, the browser will slow down and eventually the script will stop running. One-time leaks can be easily detected when memory reaches a certain size. Usually, these small one-time leaks are treated as optimization issues. But leaks that cause continuous memory growth are considered bugs and must be fixed.</p>

<p>Here we’ll use an example from <a href="https://developer.chrome.com/devtools/docs/demos/memory/example1">Chrome</a>. The full code:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="p">[];</span>

<span class="kd">function</span> <span class="nf">createSomeNodes</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">div</span><span class="p">,</span>
    <span class="nx">i</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span>
    <span class="nx">frag</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createDocumentFragment</span><span class="p">();</span>
  <span class="k">for </span><span class="p">(;</span> <span class="nx">i</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">div</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">);</span>
    <span class="nx">div</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span>
      <span class="nb">document</span><span class="p">.</span><span class="nf">createTextNode</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> - </span><span class="dl">'</span> <span class="o">+</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">().</span><span class="nf">toTimeString</span><span class="p">())</span>
    <span class="p">);</span>
    <span class="nx">frag</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">div</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">nodes</span><span class="dl">'</span><span class="p">).</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">frag</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nf">grow</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">x</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="k">new</span> <span class="nc">Array</span><span class="p">(</span><span class="mi">1000000</span><span class="p">).</span><span class="nf">join</span><span class="p">(</span><span class="dl">'</span><span class="s1">x</span><span class="dl">'</span><span class="p">));</span>
  <span class="nf">createSomeNodes</span><span class="p">();</span>
  <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">grow</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>When <code class="language-plaintext highlighter-rouge">grow</code> is called, it starts creating <code class="language-plaintext highlighter-rouge">div</code> elements and appending them to the DOM. It also creates a large array (1 million elements) and pushes it into an array referenced by a global variable (<code class="language-plaintext highlighter-rouge">x</code>). This causes memory to grow steadily, detectable with <code class="language-plaintext highlighter-rouge">Timeline view</code>.</p>

<h3 id="detecting-steady-memory-growth-in-chrome">Detecting steady memory growth in Chrome</h3>

<p>We’ll start with <a href="https://developer.chrome.com/devtools/docs/demos/memory/example1">Chrome’s example</a>. After opening the example, open Dev Tools, go to the <code class="language-plaintext highlighter-rouge">timeline</code> tab, check <code class="language-plaintext highlighter-rouge">memory</code>, and click the <code class="language-plaintext highlighter-rouge">record</code> button. Then go back to the example page and click <code class="language-plaintext highlighter-rouge">The Button</code> to start the memory leak. After a while, stop recording and examine the results:</p>

<p><img src="https://cdn.auth0.com/blog/jsleaks/example-timeline.png" alt="example-timeline" /></p>

<p>There are two major signs in the image above indicating a memory leak: the chart for <code class="language-plaintext highlighter-rouge">nodes</code> (green line) and the chart for JS heap (dark blue line). The node count keeps increasing and never decreases — a major warning sign.</p>

<p>The JS heap also grows over time, though this is harder to see due to GC effects. You can see memory go up and then down repeatedly. The key point is that after each collection, the JS heap size is still larger than after the previous collection. In other words, even though the GC successfully collected a lot of memory, some of it is leaking.</p>

<p>Now that we’re sure the program has a memory leak, we need to find the cause.</p>

<h3 id="creating-2-snapshots">Creating 2 snapshots</h3>

<p>To find the cause of the leak, we’ll use Chrome’s <code class="language-plaintext highlighter-rouge">profiles</code> tool — specifically the <code class="language-plaintext highlighter-rouge">Take Heap Snapshot</code> feature.</p>

<p>First, reload the page and take a snapshot right after loading. We’ll use this as the baseline. Then click <code class="language-plaintext highlighter-rouge">The Button</code> again, wait a few seconds, and take another snapshot. Then set a breakpoint to stop the leak.</p>

<p>There are two ways to compare snapshots. First, use <code class="language-plaintext highlighter-rouge">Summary</code> view and choose <code class="language-plaintext highlighter-rouge">Objects allocated between Snapshot 1 and Snapshot 2</code> from the dropdown. Or switch from <code class="language-plaintext highlighter-rouge">Summary</code> to <code class="language-plaintext highlighter-rouge">Comparison</code>. In both cases, you’ll see a list of objects created between the two snapshots.</p>

<p><img src="https://cdn.auth0.com/blog/jsleaks/example-snapshots-1.png" alt="example-snapshots" /></p>

<p>In this case, finding the leak is straightforward. Look at the <code class="language-plaintext highlighter-rouge">Size Delta</code> of <code class="language-plaintext highlighter-rouge">(string)</code>. 8MB with 58 new objects. This is highly suspicious: new objects are created but not freed, and 8MB is consumed.</p>

<p>If we expand the constructor list for <code class="language-plaintext highlighter-rouge">(string)</code>, we see some large objects alongside small ones. Selecting one of these large objects reveals interesting details in <code class="language-plaintext highlighter-rouge">retainers</code>:</p>

<p><img src="https://cdn.auth0.com/blog/jsleaks/example-snapshots-2.png" alt="example-snapshots" /></p>

<p>We can see the selected object is an element of an array. Then we see this array is referenced by variable <code class="language-plaintext highlighter-rouge">x</code> inside <code class="language-plaintext highlighter-rouge">window</code>. This shows the entire path from our large object to the root (<code class="language-plaintext highlighter-rouge">window</code>). We’ve found a cause of the leak and where it’s referenced.</p>

<h3 id="record-heap-allocations">Record Heap Allocations</h3>

<p>We start by letting the script continue running and go back to the <code class="language-plaintext highlighter-rouge">Profiles</code> tab in Chrome Dev Tools. Click <code class="language-plaintext highlighter-rouge">Record Heap Allocations</code>. While the tool is running, you’ll see blue bars on the chart at the top, showing object allocation as the program runs.</p>

<p><img src="https://cdn.auth0.com/blog/jsleaks/example-recordedallocs-overview.png" alt="example-recordedallocs-overview" /></p>

<p>The tool’s feature: select a time range to see which objects were allocated during that period. Place the range as close to the dark blue bars as possible. Only three constructor functions are shown in the list: one related to the <code class="language-plaintext highlighter-rouge">(string)</code> leak above, another related to DOM creation, and the last one related to <code class="language-plaintext highlighter-rouge">Text</code> creation.</p>

<p>Select one of the <code class="language-plaintext highlighter-rouge">HTMLDivElement</code> constructors and choose <code class="language-plaintext highlighter-rouge">Allocation stack</code>.</p>

<p><img src="https://cdn.auth0.com/blog/jsleaks/example-recordedallocs-selected.png" alt="example-recordedallocs-selected" /></p>

<p>From the image above, we see the element was created by <code class="language-plaintext highlighter-rouge">grow</code> -&gt; <code class="language-plaintext highlighter-rouge">createSomeNodes</code>. Looking closely at each bar on the chart, we see <code class="language-plaintext highlighter-rouge">HTMLDivElement</code> is called multiple times. Going back to the snapshot <code class="language-plaintext highlighter-rouge">comparison view</code>, we see it only creates objects without deleting them. Now that we know where objects are leaking (<code class="language-plaintext highlighter-rouge">createSomeNodes</code>), we can go back to the code and fix it.</p>

<h3 id="other-useful-features">Other useful features</h3>

<p>Instead of using <code class="language-plaintext highlighter-rouge">Summary view</code>, we can use <code class="language-plaintext highlighter-rouge">Allocation view</code>:</p>

<p><img src="https://cdn.auth0.com/blog/jsleaks/example-recordedallocs-list.png" alt="example-recordedallocs-list" /></p>

<p>This view shows a list of functions and their associated memory allocation. We can immediately see <code class="language-plaintext highlighter-rouge">grow</code> and <code class="language-plaintext highlighter-rouge">createSomeNodes</code> stand out. Selecting <code class="language-plaintext highlighter-rouge">grow</code> shows the constructor objects called. Notice <code class="language-plaintext highlighter-rouge">(string)</code>, <code class="language-plaintext highlighter-rouge">HTMLDivElement</code>, and <code class="language-plaintext highlighter-rouge">Text</code> as constructors for the leaked objects.</p>

<p><strong>Note</strong>: to use this feature, go to <code class="language-plaintext highlighter-rouge">Dev Tools</code> -&gt; Settings and enable <code class="language-plaintext highlighter-rouge">record heap allocation stack traces</code> before recording.</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="javascript" /><category term="memory" /><category term="performance" /><summary type="html"><![CDATA[Explore 4 common types of memory leaks in JavaScript: global variables, forgotten callbacks/timers, detached DOM nodes, and closures — with detection tips.]]></summary></entry><entry xml:lang="en"><title type="html">What is Node.js</title><link href="https://duclvz.github.io/en/posts/what-is-nodejs" rel="alternate" type="text/html" title="What is Node.js" /><published>2020-06-05T20:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://duclvz.github.io/posts/what-is-nodejs</id><content type="html" xml:base="https://duclvz.github.io/posts/what-is-nodejs"><![CDATA[<p>What is the essence of Node.js?</p>

<blockquote>
  <p>Node.js is a JavaScript <code class="language-plaintext highlighter-rouge">runtime</code> built on Chrome’s V8 JavaScript <code class="language-plaintext highlighter-rouge">Engine</code>.</p>
</blockquote>

<p>JavaScript is easy to understand. But what about <code class="language-plaintext highlighter-rouge">Runtime</code> and <code class="language-plaintext highlighter-rouge">Engine</code>? How do they relate?</p>

<p>A <code class="language-plaintext highlighter-rouge">JavaScript Engine</code> can be simply defined as: A program or library that executes JavaScript code, providing mechanisms for object creation, function calls, etc. It can be a simple <code class="language-plaintext highlighter-rouge">interpreter</code> or a <code class="language-plaintext highlighter-rouge">JIT compiler</code> to bytecode.</p>

<p>Of course, since this entire article aims to answer “What is Node.js,” and understanding the JavaScript Engine is already 50% of the answer, we’ll explain it again — more complicatedly and verbosely — starting from even more fundamental concepts like <code class="language-plaintext highlighter-rouge">Interpreter</code> and <code class="language-plaintext highlighter-rouge">Compiler</code>.</p>

<h2 id="interpreter-and-compiler">Interpreter and Compiler</h2>

<ul>
  <li><strong>Interpreter</strong> (of language A): A component that directly executes a piece of code (written in language A). You could think of the CPU as an interpreter of its instruction set. Today, an interpreter is usually understood as directly executing a program from source code without converting to machine code.</li>
  <li><strong>Compiler</strong>: Translates from language A to language B such that execution yields equivalent results. Usually used to translate source code from a high-level language A to a lower-level language B that is easier to <code class="language-plaintext highlighter-rouge">interpret</code>, and of course, the easiest language to interpret is machine code.</li>
</ul>

<p>Compile time is usually not small, especially when optimizing the result. To reduce compile time, one approach (trading off execution speed after compilation) is not to translate directly to machine code but to an intermediate language and use an interpreter for that intermediate language — commonly called <code class="language-plaintext highlighter-rouge">bytecode</code>. The time to compile from source to bytecode is faster than to machine code, execution is faster than directly interpreting source code, though slower than machine code.</p>

<p>Now <code class="language-plaintext highlighter-rouge">interpreter</code> and <code class="language-plaintext highlighter-rouge">bytecode</code> in the JavaScript Engine definition are clear. What about <code class="language-plaintext highlighter-rouge">JIT compiler</code>?</p>

<p>To understand <code class="language-plaintext highlighter-rouge">JIT compiler</code>, we need to view it in relation to another concept: <code class="language-plaintext highlighter-rouge">AOT compiler</code>.</p>

<p><code class="language-plaintext highlighter-rouge">Ahead-of-Time</code> (AOT) and <code class="language-plaintext highlighter-rouge">Just-in-Time</code> (JIT) compilation: The “time” referenced here is <code class="language-plaintext highlighter-rouge">runtime</code>. AOT compiles the entire source code before the program starts running; JIT compiles source code during runtime. The philosophy of JIT compilation is: instead of waiting for the compiler to translate all source code — which can take a long time — we compile the parts we need first and start running with them immediately.</p>

<p>Interpreter and compiler can combine to form the <code class="language-plaintext highlighter-rouge">engine</code> of a language in one of two ways:</p>

<ul>
  <li><strong>AOT combined with interpreter:</strong> Source code is fully compiled into machine code or bytecode before execution, then an interpreter executes it. For example, Python is AOT-compiled to CPython bytecode in a flash, and CPython runs on an interpreter.</li>
  <li><strong>JIT combined with interpreter:</strong> Fully compiled code runs faster but takes more time before starting; directly interpreting source code starts immediately but runs slowly. The compromise: use an interpreter to quickly start executing source code, then use a JIT compiler to translate and replace source code with compiled code once it’s ready.</li>
</ul>

<h2 id="v8-engine">V8 Engine</h2>

<p><code class="language-plaintext highlighter-rouge">V8</code> is an open-source JavaScript engine written in <code class="language-plaintext highlighter-rouge">C++</code>, developed by Google as part of the <code class="language-plaintext highlighter-rouge">Chromium</code> project, first released with the initial version of the Chrome browser. V8 compiles JavaScript directly to <code class="language-plaintext highlighter-rouge">native machine code</code> instead of using interpreting bytecode in the traditional way.</p>

<p>Node.js was initially built on V8 due to its astonishing execution speed compared to previous JavaScript engines — fast enough to power a high-performance <code class="language-plaintext highlighter-rouge">server-side</code> system. Today, other vendors’ engines have caught up with V8. Node.js has also released a version using Microsoft’s <code class="language-plaintext highlighter-rouge">Chakra Engine</code> at <a href="https://github.com/nodejs/node-chakracore">https://github.com/nodejs/node-chakracore</a>, but when talking about Node.js, V8 is still the standard reference.</p>

<p>The name <code class="language-plaintext highlighter-rouge">V8 Engine</code> — chosen by Google — is emotionally evocative, conjuring images of powerful car engines producing massive output from an 8-cylinder V-shaped design, rarely under 3.0L displacement and sometimes exceeding 8.0L, like the engine in the Audi R8.</p>

<p>Google’s engineers likely love cars, because they continued naming components within their V8 engine <code class="language-plaintext highlighter-rouge">Crankshaft</code>, <code class="language-plaintext highlighter-rouge">TurboFan</code>, and <code class="language-plaintext highlighter-rouge">Ignition</code> — key technical components of modern internal combustion engines that we’ll encounter later in this article.</p>

<p>But enough digression. The three key factors behind V8’s high performance are:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">Fast Property Access</code></li>
  <li><code class="language-plaintext highlighter-rouge">Dynamic Machine Code Generation</code></li>
  <li><code class="language-plaintext highlighter-rouge">Efficient Garbage Collection</code></li>
</ul>

<h3 id="fast-property-access">Fast Property Access</h3>

<p>JavaScript is a <code class="language-plaintext highlighter-rouge">dynamic programming language</code>, meaning <code class="language-plaintext highlighter-rouge">properties</code> can be added, removed, or changed at runtime. Most JavaScript Engines use a <code class="language-plaintext highlighter-rouge">dictionary</code>-like data structure to store object properties — every property access requires a <code class="language-plaintext highlighter-rouge">dynamic dictionary lookup</code> to find the property’s memory location, slower than direct property access in traditional <code class="language-plaintext highlighter-rouge">class-based</code> languages.</p>

<p>To avoid dynamic lookup, V8 automatically creates a <code class="language-plaintext highlighter-rouge">hidden class</code> for each object, turning JavaScript objects into class-based ones. Each time a property is added to an object, V8 creates a new hidden class and transitions the object to this new class.</p>

<p>Once JavaScript objects become class-based, a classic compiler optimization technique becomes viable and is incorporated into V8: <code class="language-plaintext highlighter-rouge">Inline Caching</code>, boosting JavaScript performance by up to dozens of times in long-running programs.</p>

<h3 id="dynamic-machine-code-generation">Dynamic Machine Code Generation</h3>

<p>V8 translates JavaScript source code directly to native machine code for high interpretation speed, while also being able to <code class="language-plaintext highlighter-rouge">optimize</code> (and re-optimize) compiled code at runtime based on data collected from a profiler.</p>

<p>V8 has two compilers. Initially, all your source code is parsed, converted to <code class="language-plaintext highlighter-rouge">AST</code>, and fed into the <code class="language-plaintext highlighter-rouge">Full-Codegen Compiler</code>, which produces the first machine code version of your program.</p>

<p><strong>Full-Codegen Compiler:</strong> Its job is to turn your source code into machine code <code class="language-plaintext highlighter-rouge">as fast as possible</code> — no optimization whatsoever. It also injects some <code class="language-plaintext highlighter-rouge">type-feedback code</code> to collect information for later optimization. This compiler performs no analysis and knows nothing about data types in the source code at this stage.</p>

<p>To improve performance, V8 continues monitoring the program at runtime via a <code class="language-plaintext highlighter-rouge">profiler</code> — a component in V8’s architecture that collects information to find which functions are <code class="language-plaintext highlighter-rouge">hot functions</code> (called repeatedly many times). That’s when optimization is needed for better compiled code. And that’s when <code class="language-plaintext highlighter-rouge">Crankshaft</code> steps in.</p>

<p><strong>Optimizing compiler:</strong> <code class="language-plaintext highlighter-rouge">Crankshaft</code> (and more recently <code class="language-plaintext highlighter-rouge">TurboFan</code>) makes predictions about functions based on profiler data, re-compiles, and replaces unoptimized code via <code class="language-plaintext highlighter-rouge">on-stack replacement</code> (OSR).</p>

<p>If the assumptions are wrong — for example, it assumed <code class="language-plaintext highlighter-rouge">a</code> and <code class="language-plaintext highlighter-rouge">b</code> would always be <code class="language-plaintext highlighter-rouge">number</code> in <code class="language-plaintext highlighter-rouge">a + b</code> somewhere and used direct numeric addition instead of checking types and using the appropriate <code class="language-plaintext highlighter-rouge">+</code> operator each time, but then <code class="language-plaintext highlighter-rouge">b</code> suddenly receives a <code class="language-plaintext highlighter-rouge">string</code> — it simply <code class="language-plaintext highlighter-rouge">de-optimizes</code> and falls back to the unoptimized code.</p>

<p>This is how V8 treats our source code:</p>

<p><img src="https://v8.dev/_img/ignition-interpreter/ignition-pipeline.png" alt="ignitionpipeline" /></p>

<p><em>Image source: v8project.blogspot.com</em></p>

<p>In 2016, an interpreter named <code class="language-plaintext highlighter-rouge">Ignition</code> was added to V8 with the goal of reducing memory usage on memory-constrained systems like Android.</p>

<h3 id="efficient-garbage-collection">Efficient Garbage Collection</h3>

<p>V8’s <code class="language-plaintext highlighter-rouge">garbage collector</code> is advertised as a stop-the-world, generational, accurate garbage collector that reclaims memory from objects no longer in use by the process very efficiently. How efficient, why, or whether it’s truly more efficient than other engines — I honestly can’t say.</p>

<p>Initially, JavaScript was designed to perform small, short-lived tasks — like attaching an <code class="language-plaintext highlighter-rouge">event listener</code> to a browser element. The engine back then was simply an interpreter reading and executing JavaScript source code. Over time, we demanded more from it.</p>

<p>The first application to entrust heavy tasks to JavaScript was <code class="language-plaintext highlighter-rouge">Google Maps</code>. From there, people realized the need for faster JavaScript in longer-running runtimes.</p>

<p>JIT compilation takes more initialization time than interpretation but is much faster in long runtimes. With their JavaScript-heavy web applications, Google invested heavily in pushing browsers to improve JavaScript performance, and V8 was born as a result.</p>

<p>Now, the longer a JavaScript process runs, the more optimized and higher-performing it becomes. People felt it was viable for a more demanding environment than the web browser: <code class="language-plaintext highlighter-rouge">server-side</code>.</p>

<h2 id="javascript-runtime">JavaScript Runtime</h2>

<p>Introduced as a JavaScript <code class="language-plaintext highlighter-rouge">Runtime</code>, how does Node.js differ from a JavaScript <code class="language-plaintext highlighter-rouge">Engine</code>? Inspired by a StackOverflow answer, we can roughly understand it as follows:</p>

<p>JavaScript runs inside a <code class="language-plaintext highlighter-rouge">container</code> — a program that takes your source code and executes it. This program does two things:</p>

<ul>
  <li>Parses source code and executes each executable unit.</li>
  <li>Provides some objects so JavaScript can interact with the outside world.</li>
</ul>

<p>The first part is called the <code class="language-plaintext highlighter-rouge">Engine</code>. The rest is called the <code class="language-plaintext highlighter-rouge">Runtime</code>.</p>

<p>In practice, V8 implements <code class="language-plaintext highlighter-rouge">ECMAScript</code> according to the standard, meaning anything outside the standard is absent from V8.</p>

<p>To interact with the environment, V8 provides <code class="language-plaintext highlighter-rouge">template</code> classes that wrap objects and functions written in <code class="language-plaintext highlighter-rouge">C++</code>. These C++ functions can read/write the file system, perform networking operations, or communicate with other system processes. By setting up a <code class="language-plaintext highlighter-rouge">JavaScript context</code> with a <code class="language-plaintext highlighter-rouge">global scope</code> containing <code class="language-plaintext highlighter-rouge">JavaScript instances</code> created from these templates and running our source code within this context, our code is ready to interact with the world.</p>

<p>And that’s the job of a <code class="language-plaintext highlighter-rouge">Runtime Library</code>: create a runtime environment providing <code class="language-plaintext highlighter-rouge">built-in</code> libraries as global variables for your code to use during execution, accept source code as an <code class="language-plaintext highlighter-rouge">argument</code>, and execute it in the created context.</p>

<p>In a <code class="language-plaintext highlighter-rouge">browser runtime environment</code> like Chrome, the context Chrome provides to V8 includes global variables like <code class="language-plaintext highlighter-rouge">window</code>, <code class="language-plaintext highlighter-rouge">console</code>, <code class="language-plaintext highlighter-rouge">DOM object</code>, <code class="language-plaintext highlighter-rouge">XMLHttpRequest</code>, and the timer <code class="language-plaintext highlighter-rouge">setTimeout()</code>.</p>

<p>All of these come from Chrome, not from V8 itself. Instead, V8 provides the standard built-in objects present in every JavaScript environment, described in the <code class="language-plaintext highlighter-rouge">ECMAScript Standard</code>, including data types, operators, and special objects and functions such as value properties (<code class="language-plaintext highlighter-rouge">Infinity</code>, <code class="language-plaintext highlighter-rouge">NaN</code>, <code class="language-plaintext highlighter-rouge">null</code>, <code class="language-plaintext highlighter-rouge">undefined</code>), <code class="language-plaintext highlighter-rouge">Object</code>, <code class="language-plaintext highlighter-rouge">Function</code>, <code class="language-plaintext highlighter-rouge">Boolean</code>, <code class="language-plaintext highlighter-rouge">String</code>, <code class="language-plaintext highlighter-rouge">Number</code>, <code class="language-plaintext highlighter-rouge">Map</code>, <code class="language-plaintext highlighter-rouge">Set</code>, <code class="language-plaintext highlighter-rouge">Array</code>, <code class="language-plaintext highlighter-rouge">parseInt()</code>, <code class="language-plaintext highlighter-rouge">eval()</code>, etc.</p>

<p>Leaving the browser world, leaving the DOM behind, Node.js brings us many more built-in libraries like <code class="language-plaintext highlighter-rouge">fs</code> for file system interaction, <code class="language-plaintext highlighter-rouge">http</code> and <code class="language-plaintext highlighter-rouge">https</code> for networking, <code class="language-plaintext highlighter-rouge">tls</code>, <code class="language-plaintext highlighter-rouge">tty</code>, <code class="language-plaintext highlighter-rouge">cluster</code>, <code class="language-plaintext highlighter-rouge">os</code>, etc. The issue is, we don’t always need all of these — creating a context with so many unnecessary global variables clearly isn’t a great approach.</p>

<p>Node.js therefore groups functionality into separate modules and implements a <code class="language-plaintext highlighter-rouge">module loading</code> mechanism via the <code class="language-plaintext highlighter-rouge">require</code> and <code class="language-plaintext highlighter-rouge">exports</code> keywords, enabling more flexible contexts. Naturally, this mechanism is implemented in C/C++.</p>

<p>That’s the explanation behind Node.js’s introduction as a runtime built on Chrome’s V8 JavaScript Engine, and that’s how your JavaScript code interacts with <code class="language-plaintext highlighter-rouge">low-level APIs</code> in a <code class="language-plaintext highlighter-rouge">synchronous</code> manner. V8 runs your code in a single thread, sequentially, instruction by instruction, using a structure to manage active subroutines called the <code class="language-plaintext highlighter-rouge">call stack</code>.</p>

<h2 id="call-stack-and-event-loop">Call Stack and Event Loop</h2>

<p>The call stack isn’t something new — we’ve always needed it to ensure correct program execution. It’s just that in high-level languages, providing a call stack is hidden and automated. If we push too many stack frames and exhaust the space allocated to the call stack, we face the legendary <code class="language-plaintext highlighter-rouge">Stackoverflow</code>.</p>

<p>The story of JavaScript’s call stack has been told many times. We all know a stack frame is pushed every time a function is called and popped on <code class="language-plaintext highlighter-rouge">return</code>. After sequentially processing all instructions in the program, the call stack becomes empty. A miracle called the <code class="language-plaintext highlighter-rouge">event loop</code> picks up callback functions from a construct called the <code class="language-plaintext highlighter-rouge">event queue</code> (or task queue), pushes them onto the call stack, and the V8 engine continues executing the function now sitting on the call stack.</p>

<p>This is how JavaScript performs <code class="language-plaintext highlighter-rouge">asynchronous calls</code>. This is also why, even when calling <code class="language-plaintext highlighter-rouge">setTimeout()</code> with a delay of 0, our callback still has to wait until all code in the program finishes executing (the call stack becomes empty) before being invoked.</p>

<p><img src="https://media.geeksforgeeks.org/wp-content/uploads/20250208123836185275/Event-Loop-in-JavaScript.jpg" alt="Event-loop" /></p>

<p><em>Image source: geeksforgeeks.org</em></p>

<p>V8 receives the event loop as an input parameter when initializing the environment. Different environments have their own event loop and API for creating <code class="language-plaintext highlighter-rouge">asynchronous requests</code> — which push our <code class="language-plaintext highlighter-rouge">callback function</code> into the event queue and idly wait.</p>

<p>For Node.js, its event loop implementation is <code class="language-plaintext highlighter-rouge">libuv</code>. Without libuv, the picture of an event-driven, asynchronous, non-blocking I/O Node.js would be incomplete. V8 doesn’t even know what I/O is, let alone blocking or non-blocking.</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="javascript" /><category term="nodejs" /><summary type="html"><![CDATA[A thorough explanation of Node.js: JavaScript Engine (V8), Runtime, Call Stack, Event Loop, and libuv — all the pieces that make up Node.js.]]></summary></entry><entry xml:lang="en"><title type="html">The ‘this’ Keyword in JavaScript</title><link href="https://duclvz.github.io/en/posts/this-keyword-in-javascript" rel="alternate" type="text/html" title="The ‘this’ Keyword in JavaScript" /><published>2020-05-07T20:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://duclvz.github.io/posts/this-keyword-in-javascript</id><content type="html" xml:base="https://duclvz.github.io/posts/this-keyword-in-javascript"><![CDATA[<p>JavaScript (JS) is a fairly flexible and interesting programming language. But that flexibility also brings plenty of confusion, especially for newcomers. People new to JS often assume it works like other languages such as Java or C#. But many things in JS are quite different from those languages, causing misunderstandings. One of the most confusing points is the <code class="language-plaintext highlighter-rouge">this</code> keyword, because in JS it’s not simply a reference to the current object as in other OOP languages. Let’s explore this in detail.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// app.js</span>
<span class="c1">// Fun question: guess the output of (1) and (2)</span>
<span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
    <span class="na">mMethod</span><span class="p">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// (1)</span>

<span class="kd">var</span> <span class="nx">_mMethod</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">;</span>
<span class="nf">_mMethod</span><span class="p">();</span>  <span class="c1">// (2)</span>
</code></pre></div></div>

<p>By now, some of you familiar with <code class="language-plaintext highlighter-rouge">this</code> might chuckle at me calling it a “variable.” And you’d be right — <strong>this</strong> in JS <strong>is</strong> a <strong>keyword</strong>, not a variable. You can’t directly assign a value to <code class="language-plaintext highlighter-rouge">this</code>, nor can you <code class="language-plaintext highlighter-rouge">delete</code> it. So what makes this keyword so tricky?</p>

<h3 id="the-essence-of-the-this-keyword">The essence of the <code class="language-plaintext highlighter-rouge">this</code> keyword</h3>

<p>JavaScript code executes in a specific execution context. These contexts are arranged to execute the program sequentially. Imagine each context contains a certain set of code, and the whole program arranges these contexts in a stack. Contexts are then popped and executed one by one until completion — the context at the top of the stack contains the code ready to run.</p>

<p>Each execution context has a corresponding <code class="language-plaintext highlighter-rouge">ThisBinding</code> with a constant value representing that execution context. And the keyword <code class="language-plaintext highlighter-rouge">this</code> equals the <code class="language-plaintext highlighter-rouge">ThisBinding</code> value in the currently executing context. Thus, <code class="language-plaintext highlighter-rouge">this</code> represents the current execution context and must be re-evaluated when the execution context changes.</p>

<p>There are 3 types of execution context: global, eval, and function. Global is the top-level context of the entire program, containing code not inside any function or called by eval — it’s the default execution context. Eval is the context containing code called by the <code class="language-plaintext highlighter-rouge">eval</code> function. Function is code inside a function. We’ll look at each in detail below.</p>

<h3 id="execution-contexts">Execution contexts</h3>

<h4 id="global">Global</h4>

<p>This is the execution context at the top of the context stack — the first context when the program starts. For example, in client-side code on a web page, the global context starts right after the <code class="language-plaintext highlighter-rouge">&lt;script&gt;</code> tag. In the global context, <code class="language-plaintext highlighter-rouge">ThisBinding</code> is set to the Global Object. In Node.js, this is the Node.js global object (initially an empty object); in browsers, it’s the <code class="language-plaintext highlighter-rouge">window</code> object. However, in <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>, the global object is <code class="language-plaintext highlighter-rouge">undefined</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span> <span class="c1">// global object in global context</span>

<span class="k">this</span><span class="p">.</span><span class="nx">mX</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">I love JavaScript</span><span class="dl">'</span><span class="p">;</span> <span class="c1">// using the global object</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">mX</span><span class="p">);</span> <span class="c1">// prints the value of property mX</span>

<span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span> <span class="c1">// prints current this</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// no longer the global object</span>
</code></pre></div></div>

<h4 id="eval">Eval</h4>

<p>With <code class="language-plaintext highlighter-rouge">eval</code>, we have two cases:</p>

<h5 id="direct-eval-call">Direct eval call</h5>

<p>Calling <code class="language-plaintext highlighter-rouge">eval</code> directly means calling it as shown below. In this case, <code class="language-plaintext highlighter-rouge">ThisBinding</code> is set to the enclosing context of that code.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">callMe</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">callMe</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nf">eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">callMe()</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// global object</span>

<span class="nf">eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">obj.callMe()</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// obj object</span>
</code></pre></div></div>

<h5 id="indirect-eval-call">Indirect eval call</h5>

<p>Indirect eval means calling <code class="language-plaintext highlighter-rouge">eval</code> through a variable — e.g., passing <code class="language-plaintext highlighter-rouge">eval</code> as a function parameter or assigning it to a variable. In this case, <code class="language-plaintext highlighter-rouge">ThisBinding</code> is set to the global object.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">.</span><span class="nx">callMe</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">callMe in Global Object</span><span class="dl">'</span><span class="p">);</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">callMe</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
  <span class="p">},</span>
  <span class="na">_callMe</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">_eval</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">_eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">console.log(this)</span><span class="dl">'</span><span class="p">);</span>
    <span class="nf">_eval</span><span class="p">(</span><span class="dl">'</span><span class="s1">callMe()</span><span class="dl">'</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">_callMe</span><span class="p">(</span><span class="nb">eval</span><span class="p">);</span> <span class="c1">// indirect eval via function parameter</span>

<span class="kd">var</span> <span class="nx">mEval</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">;</span> <span class="c1">// assign eval to a variable</span>

<span class="nf">mEval</span><span class="p">(</span><span class="dl">'</span><span class="s1">console.log(this)</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// indirect eval via variable mEval</span>
</code></pre></div></div>

<h4 id="function">Function</h4>

<p>When a function is called, its execution context depends on the input parameters and the calling context. Suppose our function is F, with arguments and calling context corresponding to thisValue. The <code class="language-plaintext highlighter-rouge">thisBinding</code> is determined as follows:</p>

<blockquote>
  <ol>
    <li>If the function is in strict mode, ThisBinding is set to thisValue.</li>
    <li>Else if thisValue is null or undefined, ThisBinding is set to the global object.</li>
    <li>Else if Type(thisValue) is not Object, ThisBinding is set to ToObject(thisValue).</li>
    <li>Else ThisBinding is set to thisValue</li>
  </ol>
</blockquote>

<p>See more about <code class="language-plaintext highlighter-rouge">thisBinding</code> assignment <a href="http://es5.github.io/#x10.4.3">here</a>.</p>

<p>Let’s look at some specific function call scenarios:</p>

<h5 id="calling-through-the-global-context">Calling through the global context</h5>

<p>Here, <code class="language-plaintext highlighter-rouge">this</code> references the global object.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">mMethod</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span> <span class="c1">// global object</span>
<span class="p">}</span>

<span class="nf">mMethod</span><span class="p">();</span>

<span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">myMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return </span><span class="p">(</span><span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span> <span class="c1">// global object</span>
    <span class="p">})();</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">myMethod</span><span class="p">();</span>
</code></pre></div></div>

<h5 id="calling-through-an-object">Calling through an object</h5>

<p>Here, <code class="language-plaintext highlighter-rouge">this</code> references the thisValue object — the object containing the function.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
  <span class="p">},</span>
  <span class="na">oMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">▼ oMethod</span><span class="dl">'</span><span class="p">);</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">▲  oMethod</span><span class="dl">'</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// this corresponds to obj</span>
<span class="nx">obj</span><span class="p">[</span><span class="dl">'</span><span class="s1">oMethod</span><span class="dl">'</span><span class="p">]();</span> <span class="c1">// this corresponds to obj</span>

<span class="c1">// Assign mMethod to another object</span>
<span class="kd">var</span> <span class="nx">obj1</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">"</span><span class="s2">I'm obj1</span><span class="dl">"</span><span class="p">,</span>
<span class="p">};</span>
<span class="nx">obj1</span><span class="p">.</span><span class="nx">mMethod</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">;</span>

<span class="nx">obj1</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// this corresponds to obj1</span>

<span class="c1">// Calling via object construction with new</span>
<span class="kd">function</span> <span class="nf">MyObject</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">mVal</span> <span class="o">=</span> <span class="nx">val</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">I xxx JS</span><span class="dl">'</span><span class="p">;</span>

  <span class="k">this</span><span class="p">.</span><span class="nx">mMethod</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
  <span class="p">};</span>
<span class="p">}</span>

<span class="kd">var</span> <span class="nx">mObj1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MyObject</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">mObj2</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MyObject</span><span class="p">(</span><span class="dl">"</span><span class="s2">I'm object 2</span><span class="dl">"</span><span class="p">);</span>

<span class="nx">mObj1</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// this corresponds to mObj1</span>
<span class="nx">mObj2</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// this corresponds to mObj2</span>
</code></pre></div></div>

<h5 id="calling-through-special-functions">Calling through special functions</h5>

<p>JavaScript provides built-in functions that let us control <code class="language-plaintext highlighter-rouge">this</code> via an input object:</p>

<ul>
  <li>Function.prototype.apply(thisArg, argArray)</li>
  <li>Function.prototype.call(thisArg[, arg1[, arg2, …]])</li>
  <li>Function.prototype.bind(thisArg[, arg1[, arg2, …]])</li>
  <li>Array.prototype.every(callback[, thisArg])</li>
  <li>Array.prototype.some(callback[, thisArg])</li>
  <li>Array.prototype.forEach(callback[, thisArg])</li>
  <li>Array.prototype.map(callback[, thisArg])</li>
  <li>Array.prototype.filter(callback[, thisArg])</li>
</ul>

<p>Using these functions, <code class="language-plaintext highlighter-rouge">this</code> becomes the value of the <code class="language-plaintext highlighter-rouge">thisArg</code> object. This is very handy for actively changing <code class="language-plaintext highlighter-rouge">thisBinding</code>:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">firstName</span><span class="p">,</span> <span class="nx">lastName</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="nx">firstName</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">Vô</span><span class="dl">'</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="nx">lastName</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">Danh</span><span class="dl">'</span><span class="p">;</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">);</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">obj1</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">"</span><span class="s2">I'm obj1</span><span class="dl">"</span><span class="p">,</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">obj1</span><span class="p">);</span> <span class="c1">// obj1 object</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">obj1</span><span class="p">,</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Chí</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Phèo</span><span class="dl">'</span><span class="p">]);</span> <span class="c1">// obj1 object</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">obj1</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Thị</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Nở</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// obj1 object</span>
</code></pre></div></div>

<p>The code above prints <code class="language-plaintext highlighter-rouge">this</code> as the <code class="language-plaintext highlighter-rouge">obj1</code> object, not <code class="language-plaintext highlighter-rouge">obj</code>, because <code class="language-plaintext highlighter-rouge">call</code> and <code class="language-plaintext highlighter-rouge">apply</code> directly pass <code class="language-plaintext highlighter-rouge">this</code> via the first parameter.</p>

<h3 id="common-confusion-cases">Common confusion cases</h3>

<h4 id="calling-through-a-different-context">Calling through a different context</h4>

<p>Consider this case:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vietnam</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">mVal</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">oMethod</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">;</span> <span class="c1">// oMethod is in the global context</span>

<span class="nf">oMethod</span><span class="p">();</span>
</code></pre></div></div>

<p>When this code runs, it prints <code class="language-plaintext highlighter-rouge">Hello undefined</code> because we’ve pushed <code class="language-plaintext highlighter-rouge">this</code> to the global object. How do we get the correct result <code class="language-plaintext highlighter-rouge">Hello Vietnam</code>? We use <code class="language-plaintext highlighter-rouge">bind</code> to force <code class="language-plaintext highlighter-rouge">this</code> to be the <code class="language-plaintext highlighter-rouge">obj</code> object:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vietnam</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">mVal</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">oMethod</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span> <span class="c1">// this in oMethod is forced to obj</span>

<span class="nf">oMethod</span><span class="p">();</span>
</code></pre></div></div>

<p>Why <code class="language-plaintext highlighter-rouge">bind</code> and not <code class="language-plaintext highlighter-rouge">call</code> or <code class="language-plaintext highlighter-rouge">apply</code>? Because <code class="language-plaintext highlighter-rouge">bind</code> retains the <code class="language-plaintext highlighter-rouge">obj</code> value for multiple calls, while <code class="language-plaintext highlighter-rouge">call</code> and <code class="language-plaintext highlighter-rouge">apply</code> only apply for a single invocation. Read more in the <a href="https://duclvz.github.io/en/posts/javascript-co-ban-voi-call-apply-va-bind">call, apply, and bind article</a>.</p>

<h4 id="callbacks">Callbacks</h4>

<p>Calling through a callback is essentially calling through a different context, since the callback executes in a different context:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vietnam</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">mVal</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">obj1</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">oMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nf">callback</span><span class="p">();</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj1</span><span class="p">.</span><span class="nf">oMethod</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">);</span>
</code></pre></div></div>

<p>Because it’s called in <code class="language-plaintext highlighter-rouge">obj1</code>’s context, <code class="language-plaintext highlighter-rouge">mMethod</code> now takes <code class="language-plaintext highlighter-rouge">this</code> as <code class="language-plaintext highlighter-rouge">obj1</code>, not <code class="language-plaintext highlighter-rouge">obj</code>. Again, use <code class="language-plaintext highlighter-rouge">bind</code>:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">obj1</span><span class="p">.</span><span class="nf">oMethod</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">));</span>
</code></pre></div></div>

<h4 id="nested-functions">Nested functions</h4>

<p>Let’s examine ambiguity with nested functions:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vietnam</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">oVal</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">oMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">callMe</span><span class="p">)</span> <span class="p">{</span>
      <span class="nf">callMe</span><span class="p">();</span>
    <span class="p">},</span>
  <span class="p">},</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">oVal</span><span class="p">.</span><span class="nf">oMethod</span><span class="p">(</span><span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">mVal</span><span class="p">);</span>
    <span class="p">});</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// prints: Hello undefined</span>
</code></pre></div></div>

<p>We expected it to print <code class="language-plaintext highlighter-rouge">mVal</code> from <code class="language-plaintext highlighter-rouge">obj</code>, but it prints <code class="language-plaintext highlighter-rouge">Hello undefined</code>. The reason: the execution context at <code class="language-plaintext highlighter-rouge">console.log</code> is now <code class="language-plaintext highlighter-rouge">oVal</code>. To access <code class="language-plaintext highlighter-rouge">mVal</code> from <code class="language-plaintext highlighter-rouge">obj</code>, we need to capture the execution context via an intermediate variable:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vietnam</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">oVal</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">oMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">callMe</span><span class="p">)</span> <span class="p">{</span>
      <span class="nf">callMe</span><span class="p">();</span>
    <span class="p">},</span>
  <span class="p">},</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">_this</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span> <span class="c1">// remember obj's execution context</span>

    <span class="k">this</span><span class="p">.</span><span class="nx">oVal</span><span class="p">.</span><span class="nf">oMethod</span><span class="p">(</span><span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">_this</span><span class="p">.</span><span class="nx">mVal</span><span class="p">);</span> <span class="c1">// reference obj's context</span>
    <span class="p">});</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span>
</code></pre></div></div>

<h3 id="conclusion">Conclusion</h3>

<p>The <code class="language-plaintext highlighter-rouge">this</code> keyword is a bit tricky, so when programming, we need to pay attention to the execution context to use it correctly and effectively, based on the calling context and execution context type. Be especially careful with callbacks and nested functions. We can also actively change the execution context using <code class="language-plaintext highlighter-rouge">call</code>, <code class="language-plaintext highlighter-rouge">apply</code>, or <code class="language-plaintext highlighter-rouge">bind</code> as described above.</p>

<p>For more on using Call, Apply, and Bind, read <a href="https://duclvz.github.io/en/posts/javascript-co-ban-voi-call-apply-va-bind">this article</a>.</p>

<p>Additionally, you can refer to the <a href="http://es5.github.io">ECMAScript 5.1 standard</a>.</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="javascript" /><category term="this" /><summary type="html"><![CDATA[Understanding `this` in JavaScript across execution contexts: global, function, eval, and controlling `this` with call, apply, bind.]]></summary></entry><entry xml:lang="en"><title type="html">JavaScript Basics with Call, Apply, and Bind</title><link href="https://duclvz.github.io/en/posts/javascript-basics-call-apply-bind" rel="alternate" type="text/html" title="JavaScript Basics with Call, Apply, and Bind" /><published>2020-05-06T20:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://duclvz.github.io/posts/javascript-basics-call-apply-bind</id><content type="html" xml:base="https://duclvz.github.io/posts/javascript-basics-call-apply-bind"><![CDATA[<p>As discussed in the article about the <code class="language-plaintext highlighter-rouge">this</code> keyword, execution context relates to <code class="language-plaintext highlighter-rouge">this</code> and can be directly changed using <code class="language-plaintext highlighter-rouge">call</code>, <code class="language-plaintext highlighter-rouge">apply</code>, and <code class="language-plaintext highlighter-rouge">bind</code>. This article will clarify these three methods, their differences, and their practical uses.</p>

<p>Basically, <code class="language-plaintext highlighter-rouge">call</code> and <code class="language-plaintext highlighter-rouge">apply</code> are quite similar and were introduced in ES3 according to the ECMAScript standard, while <code class="language-plaintext highlighter-rouge">bind</code> — introduced in ES5 — is fundamentally different yet closely related to the other two. So in this article, we’ll go from <code class="language-plaintext highlighter-rouge">call</code> and <code class="language-plaintext highlighter-rouge">apply</code> to <code class="language-plaintext highlighter-rouge">bind</code>.</p>

<h3 id="call-and-apply">Call and Apply</h3>

<p>Syntax:</p>

<ul>
  <li>
    <p>call()</p>

    <blockquote>
      <p>Function.prototype.call(thisArg[, arg1[, arg2, …]])</p>
    </blockquote>
  </li>
  <li>
    <p>apply()</p>
    <blockquote>
      <p>Function.prototype.apply(thisArg, argArray)</p>
    </blockquote>
  </li>
</ul>

<p>The <code class="language-plaintext highlighter-rouge">call()</code> and <code class="language-plaintext highlighter-rouge">apply()</code> methods <strong><em>invoke</em></strong> a function with a specified context via the <code class="language-plaintext highlighter-rouge">thisArg</code> parameter and corresponding input parameters. That is, they allow a function to execute with an arbitrary specified context. The difference between them is that <code class="language-plaintext highlighter-rouge">call()</code> accepts function arguments as separate parameters, while <code class="language-plaintext highlighter-rouge">apply()</code> accepts them as an array. Let’s look at an example:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">firstName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vô</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">lastName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Danh</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">firstName</span><span class="p">,</span> <span class="nx">lastName</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="nx">firstName</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">firstName</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="nx">lastName</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">lastName</span><span class="p">;</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">obj1</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">firstName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Ông</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">lastName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Ké</span><span class="dl">'</span><span class="p">,</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">();</span> <span class="c1">// Hello Vô Danh</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">obj1</span><span class="p">);</span> <span class="c1">// Hello Ông Ké</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">obj1</span><span class="p">);</span> <span class="c1">// Hello Ông Ké</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nx">obj1</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Thị</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Nở</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// Hello Thị Nở</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">obj1</span><span class="p">,</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Chí</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Phèo</span><span class="dl">'</span><span class="p">]);</span> <span class="c1">// Hello Chí Phèo</span>
</code></pre></div></div>

<p>From the code above, we can see that after calling <code class="language-plaintext highlighter-rouge">call()</code> or <code class="language-plaintext highlighter-rouge">apply()</code>, the execution context of <code class="language-plaintext highlighter-rouge">mMethod</code> has been switched to <code class="language-plaintext highlighter-rouge">obj1</code>. <code class="language-plaintext highlighter-rouge">call()</code> lets us pass input parameters individually, while <code class="language-plaintext highlighter-rouge">apply()</code> lets us pass them as an array.</p>

<p>Since ES5, <code class="language-plaintext highlighter-rouge">apply()</code> can also accept an array-like object instead of an array:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">obj1</span><span class="p">,</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Chí</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Phèo</span><span class="dl">'</span><span class="p">]);</span> <span class="c1">// Hello Chí Phèo</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">obj1</span><span class="p">,</span> <span class="p">{</span> <span class="na">length</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Chí</span><span class="dl">'</span><span class="p">,</span> <span class="mi">1</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Phèo</span><span class="dl">'</span> <span class="p">});</span> <span class="c1">// Hello Chí Phèo</span>
</code></pre></div></div>

<p>Using <code class="language-plaintext highlighter-rouge">call()</code> or <code class="language-plaintext highlighter-rouge">apply()</code>, we can do many clever things like borrowing a method from another context, pushing execution context to a callback, or flexibly changing how parameters are passed:</p>

<ul>
  <li>Passing execution context to a callback</li>
</ul>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">print</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">mVal</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">'</span><span class="s1">I love JavaScript</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// pass the current object to the callback</span>
    <span class="nx">callback</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nf">mMethod</span><span class="p">(</span><span class="nx">print</span><span class="p">);</span>
</code></pre></div></div>

<ul>
  <li>Changing how function parameters are passed</li>
</ul>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Math.min([value1[,value2[, ...]]])</span>
<span class="c1">// Use an array for input instead of discrete values</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">219</span><span class="p">]));</span> <span class="c1">// -1</span>
</code></pre></div></div>

<p>Not bad, right? With <code class="language-plaintext highlighter-rouge">call</code> and <code class="language-plaintext highlighter-rouge">apply</code>, we gain flexibility in programming, saving effort on cumbersome transformations and reusing code effectively.</p>

<h3 id="bind">Bind</h3>

<p>Syntax:</p>

<blockquote>
  <p>Function.prototype.bind(thisArg[, arg1[, arg2, …]])</p>
</blockquote>

<p>The <code class="language-plaintext highlighter-rouge">bind()</code> method <strong><em>creates</em></strong> a <strong><em>new function</em></strong> whose body is the same as the called function but bound to a specified execution context via the <code class="language-plaintext highlighter-rouge">thisArg</code> parameter. Unlike <code class="language-plaintext highlighter-rouge">call()</code> and <code class="language-plaintext highlighter-rouge">apply()</code>, <code class="language-plaintext highlighter-rouge">bind()</code> does not immediately execute the function — it stores the execution context for later use:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">mVal</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vietnam</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">mVal</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">oMethod</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span> <span class="c1">// this in oMethod is forced to be obj</span>

<span class="nf">oMethod</span><span class="p">();</span> <span class="c1">// Hello Vietnam</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mVal</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Hanoi</span><span class="dl">'</span><span class="p">;</span>

<span class="nf">oMethod</span><span class="p">();</span> <span class="c1">// Hello Hanoi</span>
</code></pre></div></div>

<p>Unlike <code class="language-plaintext highlighter-rouge">call()</code> and <code class="language-plaintext highlighter-rouge">apply()</code>, calling <code class="language-plaintext highlighter-rouge">bind()</code> doesn’t execute the function immediately — it only binds the execution context for <code class="language-plaintext highlighter-rouge">mMethod</code>. Because <code class="language-plaintext highlighter-rouge">mMethod</code> is bound to the <code class="language-plaintext highlighter-rouge">obj</code> context, every execution uses <code class="language-plaintext highlighter-rouge">this</code> as the <code class="language-plaintext highlighter-rouge">obj</code> object. As shown above, after changing <code class="language-plaintext highlighter-rouge">mVal</code> in <code class="language-plaintext highlighter-rouge">obj</code>, <code class="language-plaintext highlighter-rouge">mMethod</code> prints the updated value.</p>

<p>Essentially, <code class="language-plaintext highlighter-rouge">bind()</code> can be implemented as follows:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">Function</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">bind</span> <span class="o">=</span> <span class="nf">function </span><span class="p">(</span><span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">_this</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
  <span class="k">return</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">_this</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">context</span><span class="p">,</span> <span class="nx">arguments</span><span class="p">);</span>
  <span class="p">};</span>
<span class="p">};</span>
</code></pre></div></div>

<p>By using <code class="language-plaintext highlighter-rouge">apply()</code>, we can change the execution context for a function, and to persist that context for later execution, we create a new function as shown above.</p>

<p>Because of its context-persisting nature, <code class="language-plaintext highlighter-rouge">bind()</code> is commonly used with callbacks such as click event handlers. For example, when using jQuery, <code class="language-plaintext highlighter-rouge">this</code> in click event callbacks is automatically bound to the button element.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;!doctype html&gt;</span>
<span class="nt">&lt;html&gt;</span>
  <span class="nt">&lt;head&gt;</span>
    <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
    <span class="nt">&lt;script&gt;</span>
      <span class="nf">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nf">ready</span><span class="p">(</span><span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
        <span class="nf">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#btn</span><span class="dl">'</span><span class="p">).</span><span class="nf">click</span><span class="p">(</span><span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
          <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
          <span class="nf">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nf">text</span><span class="p">(</span><span class="nc">Number</span><span class="p">(</span><span class="nf">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nf">text</span><span class="p">())</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
        <span class="p">});</span>
      <span class="p">});</span>
    <span class="nt">&lt;/script&gt;</span>
  <span class="nt">&lt;/head&gt;</span>
  <span class="nt">&lt;body&gt;</span>
    <span class="nt">&lt;button</span> <span class="na">id=</span><span class="s">"btn"</span><span class="nt">&gt;</span>0<span class="nt">&lt;/button&gt;</span>
  <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre></div></div>

<p>Additionally, we can do many interesting things like creating shortcuts for functions or grouping parameters:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">firstName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Thánh</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">lastName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Gióng</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">hello</span><span class="p">,</span> <span class="nx">firstName</span><span class="p">,</span> <span class="nx">lastName</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">hello</span> <span class="o">=</span> <span class="nx">hello</span> <span class="o">||</span> <span class="dl">'</span><span class="s1">Hello</span><span class="dl">'</span><span class="p">,</span>
      <span class="nx">firstName</span> <span class="o">=</span> <span class="nx">firstName</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">firstName</span><span class="p">,</span>
      <span class="nx">lastName</span> <span class="o">=</span> <span class="nx">lastName</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">lastName</span><span class="p">;</span>

    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">hello</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="c1">// create shortcut</span>
<span class="kd">var</span> <span class="nx">print</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
<span class="nf">print</span><span class="p">();</span>

<span class="kd">var</span> <span class="nx">print</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Hello</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Mr</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Bean</span><span class="dl">'</span><span class="p">);</span>
<span class="nf">print</span><span class="p">();</span>

<span class="c1">// Group by greeting</span>
<span class="nx">print</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Xin chào bạn</span><span class="dl">'</span><span class="p">);</span>
<span class="nf">print</span><span class="p">();</span>

<span class="c1">// Group by firstName</span>
<span class="nx">print</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Kính chào ngài</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Nguyễn</span><span class="dl">'</span><span class="p">);</span>
<span class="nf">print</span><span class="p">(</span><span class="dl">'</span><span class="s1">Trãi</span><span class="dl">'</span><span class="p">);</span>
<span class="nf">print</span><span class="p">(</span><span class="dl">'</span><span class="s1">Xiển</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>

<h3 id="a-fun-trick">A fun trick</h3>

<p>As analyzed above, when we need to execute a function in a different context, we must use <code class="language-plaintext highlighter-rouge">call</code>, <code class="language-plaintext highlighter-rouge">apply</code>, or <code class="language-plaintext highlighter-rouge">bind</code>. But there’s a way to bypass them:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">firstName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Vô</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">lastName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Danh</span><span class="dl">'</span><span class="p">,</span>

  <span class="na">mMethod</span><span class="p">:</span> <span class="nf">function </span><span class="p">(</span><span class="nx">firstName</span><span class="p">,</span> <span class="nx">lastName</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">firstName</span> <span class="o">=</span> <span class="nx">firstName</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">firstName</span><span class="p">;</span>
    <span class="kd">var</span> <span class="nx">lastName</span> <span class="o">=</span> <span class="nx">lastName</span> <span class="o">||</span> <span class="k">this</span><span class="p">.</span><span class="nx">lastName</span><span class="p">;</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">firstName</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">lastName</span><span class="p">);</span>
  <span class="p">},</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">obj1</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">firstName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Ông</span><span class="dl">'</span><span class="p">,</span>
  <span class="na">lastName</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Ké</span><span class="dl">'</span><span class="p">,</span>
<span class="p">};</span>

<span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">obj1</span><span class="p">);</span> <span class="c1">// Hello Ông Ké</span>

<span class="c1">// bypass here</span>
<span class="kd">var</span> <span class="nx">method</span> <span class="o">=</span> <span class="nb">Function</span><span class="p">.</span><span class="nx">call</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">mMethod</span><span class="p">);</span>

<span class="nf">method</span><span class="p">(</span><span class="nx">obj1</span><span class="p">);</span> <span class="c1">// Hello Ông Ké</span>

<span class="c1">// bypass in object prototype</span>
<span class="nx">method</span> <span class="o">=</span> <span class="nb">Function</span><span class="p">.</span><span class="nx">call</span><span class="p">.</span><span class="nf">bind</span><span class="p">(</span><span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">);</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">method</span><span class="p">([</span><span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">40</span><span class="p">],</span> <span class="mi">1</span><span class="p">));</span> <span class="c1">// [20, 40]</span>
</code></pre></div></div>

<p>With the code above, when calling <code class="language-plaintext highlighter-rouge">method</code>, we no longer need to call <code class="language-plaintext highlighter-rouge">call</code>, <code class="language-plaintext highlighter-rouge">apply</code>, or <code class="language-plaintext highlighter-rouge">bind</code> — we just directly pass the target object and parameters. Quite neat, right?</p>

<p>This works because all functions in JavaScript inherit from <code class="language-plaintext highlighter-rouge">Function.prototype</code>, so they naturally have all methods defined on <code class="language-plaintext highlighter-rouge">Function.prototype</code> like <code class="language-plaintext highlighter-rouge">call</code>, <code class="language-plaintext highlighter-rouge">apply</code>, or <code class="language-plaintext highlighter-rouge">bind</code>. Thus, we can call these inherited methods from any function.</p>

<p>In the example above, we treat <code class="language-plaintext highlighter-rouge">obj.mMethod</code> as the object to call <code class="language-plaintext highlighter-rouge">call</code> on, creating a <code class="language-plaintext highlighter-rouge">method</code> directly from <code class="language-plaintext highlighter-rouge">call</code> that has been bound with <code class="language-plaintext highlighter-rouge">thisVal</code> equal to <code class="language-plaintext highlighter-rouge">obj.mMethod</code>: <code class="language-plaintext highlighter-rouge">Function.call.bind(obj.mMethod)</code> or <code class="language-plaintext highlighter-rouge">Function.prototype.call.bind(obj.mMethod)</code>. In other words, the new <code class="language-plaintext highlighter-rouge">method</code> has the same body as <code class="language-plaintext highlighter-rouge">call</code> and its owner (<code class="language-plaintext highlighter-rouge">this</code>) is <code class="language-plaintext highlighter-rouge">obj.mMethod</code>, so <code class="language-plaintext highlighter-rouge">method()</code> ~ <code class="language-plaintext highlighter-rouge">obj.mMethod.call()</code>.</p>

<h3 id="conclusion">Conclusion</h3>

<p>Using <code class="language-plaintext highlighter-rouge">call</code>, <code class="language-plaintext highlighter-rouge">apply</code>, and <code class="language-plaintext highlighter-rouge">bind</code>, we can change the execution context to use a function more flexibly — executing it for a different object or scope, maximizing code reuse, creating function shortcuts, and handling input parameters more flexibly. With <code class="language-plaintext highlighter-rouge">call</code> and <code class="language-plaintext highlighter-rouge">apply</code>, we execute the function immediately; with <code class="language-plaintext highlighter-rouge">bind</code>, we can execute it multiple times after it has been bound to a specific context.</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="javascript" /><category term="call" /><category term="apply" /><category term="bind" /><summary type="html"><![CDATA[Understanding call, apply, and bind in JavaScript: how to change execution context, pass arguments flexibly, and advanced usage patterns.]]></summary></entry><entry xml:lang="en"><title type="html">The Nature of Async and Await in JavaScript</title><link href="https://duclvz.github.io/en/posts/nature-of-async-await-javascript" rel="alternate" type="text/html" title="The Nature of Async and Await in JavaScript" /><published>2020-05-05T20:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://duclvz.github.io/posts/nature-of-async-await-javascript</id><content type="html" xml:base="https://duclvz.github.io/posts/nature-of-async-await-javascript"><![CDATA[<p>With older JavaScript specifications, we had to use callbacks to handle asynchronous operations. However, this led to <a href="https://stackoverflow.com/questions/25098066/what-is-callback-hell-and-how-and-why-rx-solves-it">callback hell</a> when multiple async operations depended on each other. Callback hell makes our code messy and hard to maintain.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span>
  <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">cb</span><span class="p">,</span> <span class="nx">ms</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">almost there...</span><span class="dl">'</span><span class="p">);</span>
  <span class="nf">wait</span><span class="p">(</span><span class="mi">2007</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hold on...</span><span class="dl">'</span><span class="p">);</span>
    <span class="nf">wait</span><span class="p">(</span><span class="mi">2012</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">just a bit more...</span><span class="dl">'</span><span class="p">);</span>
      <span class="nf">wait</span><span class="p">(</span><span class="mi">2016</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">done!</span><span class="dl">'</span><span class="p">);</span>
      <span class="p">});</span>
    <span class="p">});</span>
  <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>So with ES6 (ES 2015), <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a> was introduced by default to solve callback hell. With Promises, our code looks closer to synchronous style, making it easier to follow and maintain. However, using <code class="language-plaintext highlighter-rouge">Promise</code> gave rise to a “somewhat” similar problem: Promise hell.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">almost there...</span><span class="dl">'</span><span class="p">);</span>
  <span class="nf">wait</span><span class="p">(</span><span class="mi">2007</span><span class="p">)</span>
    <span class="p">.</span><span class="nf">then</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hold on...</span><span class="dl">'</span><span class="p">);</span>
      <span class="k">return</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2007</span><span class="p">);</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="nf">then</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">just a bit more...</span><span class="dl">'</span><span class="p">);</span>
      <span class="k">return</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2012</span><span class="p">);</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="nf">then</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">just a bit more...</span><span class="dl">'</span><span class="p">);</span>
      <span class="k">return</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2016</span><span class="p">);</span>
    <span class="p">})</span>
    <span class="p">.</span><span class="nf">then</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">done!</span><span class="dl">'</span><span class="p">);</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<p>To solve this, ES7 (ES 2017) introduced async functions (<code class="language-plaintext highlighter-rouge">async / await</code>). Async functions let us write asynchronous operations in a synchronous style, making code cleaner, more readable, and “easier to understand.”</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">almost there...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2007</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hold on...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2012</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">just a bit more...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2016</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">done!</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="how-to-use">How to use</h3>

<p>To use an async function, declare the <code class="language-plaintext highlighter-rouge">async</code> keyword right before the function definition keyword. For functions defined with <code class="language-plaintext highlighter-rouge">function</code>, declare it before <code class="language-plaintext highlighter-rouge">function</code>; for arrow functions, before the parameter list; for class methods, right before the method name.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// regular function</span>
<span class="k">async</span> <span class="kd">function</span> <span class="nf">functionName</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">ret</span> <span class="o">=</span> <span class="k">await</span> <span class="k">new</span> <span class="nc">Google</span><span class="p">().</span><span class="nf">search</span><span class="p">(</span><span class="dl">'</span><span class="s1">JavaScript</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// arrow function</span>
<span class="kd">let</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="dl">'</span><span class="s1">JS</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">node.js</span><span class="dl">'</span><span class="p">].</span><span class="nf">map</span><span class="p">(</span><span class="k">async </span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return</span> <span class="k">await</span> <span class="k">new</span> <span class="nc">Google</span><span class="p">().</span><span class="nf">search</span><span class="p">(</span><span class="nx">val</span><span class="p">);</span>
<span class="p">});</span>

<span class="c1">// Class</span>
<span class="kd">class</span> <span class="nc">Google</span> <span class="p">{</span>
  <span class="nf">constructor</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">apiKey</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">...</span><span class="dl">'</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">async</span> <span class="nf">search</span><span class="p">(</span><span class="nx">keyword</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nf">searchApi</span><span class="p">(</span><span class="nx">keyword</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>With the <code class="language-plaintext highlighter-rouge">async</code> keyword, we can await <code class="language-plaintext highlighter-rouge">Promise</code> (async operations) within the function without blocking the main thread using <code class="language-plaintext highlighter-rouge">await</code>.</p>

<p>An async function always returns a Promise, whether or not you use <code class="language-plaintext highlighter-rouge">await</code>. This Promise will be in a fulfilled state with the result returned via <code class="language-plaintext highlighter-rouge">return</code>, or in a rejected state with the result thrown via <code class="language-plaintext highlighter-rouge">throw</code>.</p>

<p>Thus, the essence of an async function is Promise. If you haven’t learned about <code class="language-plaintext highlighter-rouge">Promise</code> yet, read up <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise">here</a>.</p>

<p>With Promises, we can handle exceptions with <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch"><code class="language-plaintext highlighter-rouge">catch</code></a> quite simply. But it’s not always easy to track and read. With async functions, this is extremely simple using <code class="language-plaintext highlighter-rouge">try catch</code>, just like synchronous operations.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">runner</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">almost there...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2007</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hold on...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2012</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">just a bit more...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2016</span><span class="p">);</span>
  <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="mi">2016</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="k">await</span> <span class="nf">runner</span><span class="p">();</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">done!</span><span class="dl">'</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`problem at </span><span class="p">${</span><span class="nx">e</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Nice! Clearly, code using <code class="language-plaintext highlighter-rouge">async/await</code> looks simpler, easier to follow, “easier to understand,” and solves the callback/promise hell problem. However, using it isn’t always straightforward. Let’s look at some common cases below.</p>

<h3 id="gotchas">Gotchas</h3>

<h4 id="forgetting-the-async-keyword">Forgetting the <code class="language-plaintext highlighter-rouge">async</code> keyword</h4>

<p>Obviously, without this keyword, you don’t have an async function and can’t use <code class="language-plaintext highlighter-rouge">await</code>. You might think it’s impossible to forget, but it can happen — for instance, when declaring a function inside an async function. Nested functions must also be declared with <code class="language-plaintext highlighter-rouge">async</code> if you want to use <code class="language-plaintext highlighter-rouge">await</code> inside them.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span>
  <span class="kd">let</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">500</span><span class="p">].</span><span class="nf">map</span><span class="p">(</span><span class="nx">val</span> <span class="o">=&gt;</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">val</span><span class="p">))</span>
  <span class="nx">arr</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nx">func</span> <span class="o">=&gt;</span> <span class="k">await</span> <span class="nx">func</span><span class="p">)</span>
  <span class="c1">// ??? error</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="confusion-with-the-await-keyword">Confusion with the <code class="language-plaintext highlighter-rouge">await</code> keyword</h4>

<p>Two typical scenarios:</p>

<ul>
  <li>
    <p><strong>Forgetting <code class="language-plaintext highlighter-rouge">await</code> when you need to wait for an async operation</strong></p>

    <p>Is this dangerous? Yes! If you omit <code class="language-plaintext highlighter-rouge">await</code>, you’ll get a <code class="language-plaintext highlighter-rouge">Promise</code> instead of the actual result of the async operation.</p>

    <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nf">now</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">t</span> <span class="o">=</span> <span class="nf">now</span><span class="p">();</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">t</span><span class="p">);</span>
  <span class="c1">// ??? `t` is a `Promise` instance</span>
<span class="p">}</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p><strong>Adding “unnecessary” <code class="language-plaintext highlighter-rouge">await</code> before a synchronous operation</strong></p>

    <p>Afraid of forgetting, so you sprinkle <code class="language-plaintext highlighter-rouge">await</code> everywhere? It’s not harmful except for two issues: you can no longer tell what’s sync and what’s async, and performance degrades. Every <code class="language-plaintext highlighter-rouge">await</code> implicitly expects a <code class="language-plaintext highlighter-rouge">Promise</code> — if it’s not a Promise, it gets wrapped in one via <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve"><code class="language-plaintext highlighter-rouge">Promise.resolve(value)</code></a>. That’s taking the long way around for <code class="language-plaintext highlighter-rouge">1 + 0 = 1</code>.</p>

    <div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">run with await</span><span class="dl">'</span><span class="p">);</span>
  <span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">1000000</span><span class="p">;</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">time</span><span class="p">(</span><span class="dl">'</span><span class="s1">await</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">while </span><span class="p">(</span><span class="nx">i</span><span class="o">--</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">let</span> <span class="nx">t</span> <span class="o">=</span> <span class="k">await </span><span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="mi">0</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">timeEnd</span><span class="p">(</span><span class="dl">'</span><span class="s1">await</span><span class="dl">'</span><span class="p">);</span>

  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">run without await</span><span class="dl">'</span><span class="p">);</span>
  <span class="nx">i</span> <span class="o">=</span> <span class="mi">1000000</span><span class="p">;</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">time</span><span class="p">(</span><span class="dl">'</span><span class="s1">normal</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">while </span><span class="p">(</span><span class="nx">i</span><span class="o">--</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="kd">let</span> <span class="nx">t</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="mi">0</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">timeEnd</span><span class="p">(</span><span class="dl">'</span><span class="s1">normal</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>    </div>
  </li>
</ul>

<h4 id="forgetting-error-handling">Forgetting error handling</h4>

<p>Just like forgetting <code class="language-plaintext highlighter-rouge">catch</code> with Promises, forgetting <code class="language-plaintext highlighter-rouge">try catch</code> with async functions can happen. If you forget to catch errors, an async operation failure can crash your program.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">ms</span> <span class="o">&gt;</span> <span class="mi">2015</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="nx">ms</span><span class="p">);</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">almost there...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2007</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">hold on...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2012</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">just a bit more...</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2016</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">done!</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="losing-parallelism">Losing parallelism</h4>

<p>This is probably the biggest one. If you chain <code class="language-plaintext highlighter-rouge">await</code> sequentially, your program will run like a turtle. Each <code class="language-plaintext highlighter-rouge">await</code> blocks until that operation completes.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">time</span><span class="p">(</span><span class="dl">'</span><span class="s1">wait3s</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
  <span class="k">await</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2000</span><span class="p">);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">timeEnd</span><span class="p">(</span><span class="dl">'</span><span class="s1">wait3s</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This takes a total of <code class="language-plaintext highlighter-rouge">1 + 2 = 3s</code> to execute because you must wait for each <code class="language-plaintext highlighter-rouge">wait</code> call. How to avoid this? Start the async operations first, then collect the results later. Since <code class="language-plaintext highlighter-rouge">Promise</code> allows us to retrieve the result whenever it’s in a final state, we can fire them off early:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">time</span><span class="p">(</span><span class="dl">'</span><span class="s1">wait2s</span><span class="dl">'</span><span class="p">);</span>
  <span class="kd">let</span> <span class="nx">w1</span> <span class="o">=</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
  <span class="kd">let</span> <span class="nx">w2</span> <span class="o">=</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2000</span><span class="p">);</span>
  <span class="k">await</span> <span class="nx">w1</span><span class="p">;</span>
  <span class="k">await</span> <span class="nx">w2</span><span class="p">;</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">timeEnd</span><span class="p">(</span><span class="dl">'</span><span class="s1">wait2s</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This only takes <code class="language-plaintext highlighter-rouge">2s</code> because our <code class="language-plaintext highlighter-rouge">wait</code> calls run in parallel. Besides awaiting each Promise individually, we can use <a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all"><code class="language-plaintext highlighter-rouge">Promise.all</code></a> to parallelize them:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">time</span><span class="p">(</span><span class="dl">'</span><span class="s1">wait2s</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">await</span> <span class="nb">Promise</span><span class="p">.</span><span class="nf">all</span><span class="p">([</span><span class="nf">wait</span><span class="p">(</span><span class="mi">1000</span><span class="p">),</span> <span class="nf">wait</span><span class="p">(</span><span class="mi">2000</span><span class="p">)]);</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">timeEnd</span><span class="p">(</span><span class="dl">'</span><span class="s1">wait2s</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>You might think <code class="language-plaintext highlighter-rouge">Promise.all</code> and <code class="language-plaintext highlighter-rouge">await</code>-ing each Promise are the same, but they differ. <code class="language-plaintext highlighter-rouge">Promise.all</code> only succeeds when all passed Promises succeed; it fails as soon as any one fails. So if you want to tolerate individual failures, you can’t use <code class="language-plaintext highlighter-rouge">Promise.all</code>. You must use <code class="language-plaintext highlighter-rouge">await</code> with <code class="language-plaintext highlighter-rouge">try catch</code> for each Promise:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">ms</span> <span class="o">&gt;</span> <span class="mi">2000</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">Error</span><span class="p">(</span><span class="nx">ms</span><span class="p">);</span>
  <span class="k">return</span> <span class="k">new</span> <span class="nc">Promise</span><span class="p">((</span><span class="nx">r</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setTimeout</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">ms</span><span class="p">));</span>
<span class="p">}</span>

<span class="k">async</span> <span class="kd">function</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">dur</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1000</span><span class="p">,</span> <span class="mi">2000</span><span class="p">,</span> <span class="mi">3000</span><span class="p">,</span> <span class="mi">4000</span><span class="p">];</span>
  <span class="kd">let</span> <span class="nx">all</span> <span class="o">=</span> <span class="nx">dur</span><span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">ms</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">));</span>
  <span class="k">try</span> <span class="p">{</span>
    <span class="k">await</span> <span class="nb">Promise</span><span class="p">.</span><span class="nf">all</span><span class="p">(</span><span class="nx">all</span><span class="p">);</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Promise.all - done</span><span class="dl">'</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">'</span><span class="s1">Promise.all:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">e</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="kd">let</span> <span class="nx">each</span> <span class="o">=</span> <span class="nx">dur</span><span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">ms</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">wait</span><span class="p">(</span><span class="nx">ms</span><span class="p">));</span>
  <span class="nx">each</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="k">async </span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
      <span class="k">await</span> <span class="nx">func</span><span class="p">;</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">each - done:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">dur</span><span class="p">[</span><span class="nx">index</span><span class="p">]);</span>
    <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="dl">'</span><span class="s1">each:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">e</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="platformbrowser-support">Platform/browser support</h3>

<p>At the time of writing, the following platforms and browsers support async functions:</p>

<ul>
  <li>Node.js v7.0 with <code class="language-plaintext highlighter-rouge">--harmony-async-await</code> flag</li>
  <li>Chrome v55</li>
  <li>Microsoft Edge v21.10547</li>
</ul>

<p>If you need to run on unsupported platforms/browsers, you can use Babel:</p>

<ul>
  <li>Babel <a href="https://babeljs.io/docs/plugins/transform-async-to-generator/">async-to-generator plugin</a></li>
</ul>

<h3 id="conclusion">Conclusion</h3>

<p>The essence of async functions is <code class="language-plaintext highlighter-rouge">Promise</code>, so to use them, you need <code class="language-plaintext highlighter-rouge">Promise</code> for handling async operations. You can’t use <code class="language-plaintext highlighter-rouge">await</code> to wait for callback-based functions — you must wrap them in a Promise first.</p>

<p>Although async functions have very clear syntax, we still need to be careful about misusing keywords that cause bugs or obscure program logic. And especially watch out for accidentally destroying parallelism.</p>

<p>Given the convenience of async functions, we should adopt them now to reduce future maintenance burden. For platforms/browsers without native support, we can transpile with <a href="https://babeljs.io/">Babel</a>.</p>

<p>Happy <code class="language-plaintext highlighter-rouge">await</code>-ing!</p>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="javascript" /><category term="async" /><category term="await" /><summary type="html"><![CDATA[From callback hell to Promises to async/await — understanding the fundamentals, proper usage, and common pitfalls: forgetting await, losing parallelism, missing catch.]]></summary></entry><entry xml:lang="en"><title type="html">Array Surprises in JavaScript</title><link href="https://duclvz.github.io/en/posts/array-surprises-in-javascript" rel="alternate" type="text/html" title="Array Surprises in JavaScript" /><published>2020-05-04T20:00:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://duclvz.github.io/posts/array-surprises-in-javascript</id><content type="html" xml:base="https://duclvz.github.io/posts/array-surprises-in-javascript"><![CDATA[<p>Having worked with several programming languages (Java, C, C++, C#, Objective-C, PHP), each has its own charm. But when I encountered JavaScript (JS), I suddenly fell in love — with its sexy and surprising nature. Arrays in JS, for instance, are very special and surprising. In this article, I’ll note down some points that may surprise others as they surprised me.</p>

<h3 id="how-do-you-get-the-length-of-an-array">How do you get the length of an array?</h3>

<p>Yesterday while coding, I used the <code class="language-plaintext highlighter-rouge">length</code> property to get array length and noticed a discrepancy with the number of elements retrieved, which surprised me. Re-reading JS documentation, I realized there seems to be no property storing the count of actual elements (non-<code class="language-plaintext highlighter-rouge">undefined</code>) in it. Or at least I haven’t found one. If any expert can enlighten me, that would be great. Try the following code and you’ll see that the <code class="language-plaintext highlighter-rouge">length</code> property equals the largest index plus 1.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">index 20</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">js</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">JavaScript</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">arr</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
</code></pre></div></div>

<p>This prints the length of <code class="language-plaintext highlighter-rouge">arr</code> as 21 — the largest index (20) plus 1. A bit surprising because I initially thought it would return 3 (the number of non-<code class="language-plaintext highlighter-rouge">undefined</code> elements).</p>

<p>Do non-numeric indices affect anything? The answer is: nothing regarding <code class="language-plaintext highlighter-rouge">length</code>. You can see in the following example that <code class="language-plaintext highlighter-rouge">length</code> does not depend on non-numeric indices.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">arr</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">js</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">JavaScript</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">me</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Java Lover</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">arr</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
</code></pre></div></div>

<p>This always prints 0, proving that non-numeric indices have no effect on the <code class="language-plaintext highlighter-rouge">length</code> property.</p>

<p>So the question is: how do you get the exact count of elements in an array?</p>

<p>A simple approach is to iterate and count. But it’s not as simple as we think.</p>

<h3 id="how-do-you-iterate-over-an-array">How do you iterate over an array?</h3>

<p>Iterating arrays in JS is also very interesting. The usual way is to get <code class="language-plaintext highlighter-rouge">length</code> and loop from start to end:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">index 20</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">me</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Java Lover</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for </span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">: </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
  <span class="k">if </span><span class="p">(</span><span class="k">typeof</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">!=</span> <span class="dl">'</span><span class="s1">undefined</span><span class="dl">'</span><span class="p">)</span> <span class="nx">counter</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">The size of array: %d</span><span class="dl">'</span><span class="p">,</span> <span class="nx">counter</span><span class="p">);</span>
</code></pre></div></div>

<p>The result shows elements with indices 0–9 and 11–19 as <code class="language-plaintext highlighter-rouge">undefined</code>, and counter is 2.
So <code class="language-plaintext highlighter-rouge">counter</code> doesn’t give the right result, and for large arrays (1000 elements, for example), we can’t iterate this way. Let’s try <code class="language-plaintext highlighter-rouge">Array.forEach</code>:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">index 20</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">me</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">XXX Lover</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nf">function </span><span class="p">(</span><span class="nx">ele</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">array</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">: </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">ele</span><span class="p">);</span>
  <span class="nx">counter</span><span class="o">++</span><span class="p">;</span>
<span class="p">});</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">The size of array: %d</span><span class="dl">'</span><span class="p">,</span> <span class="nx">counter</span><span class="p">);</span>
</code></pre></div></div>

<p>This also doesn’t work — same result as iterating by <code class="language-plaintext highlighter-rouge">length</code>. Another way is <code class="language-plaintext highlighter-rouge">for in</code>:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">index 20</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">me</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Java Lover</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for </span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">arr</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="dl">'</span><span class="s1">: </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
  <span class="nx">counter</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">The size of array: %d</span><span class="dl">'</span><span class="p">,</span> <span class="nx">counter</span><span class="p">);</span>
</code></pre></div></div>

<p>This gives the exact result, printing each element and returning a size of 3.</p>

<p>From this, we can see that we should be careful with the <code class="language-plaintext highlighter-rouge">length</code> property and choose the right iteration method. For contiguous data, iterating by <code class="language-plaintext highlighter-rouge">length</code> or <code class="language-plaintext highlighter-rouge">Array.forEach</code> works fine. But for sparse data and non-numeric indices, use <code class="language-plaintext highlighter-rouge">for in</code>.</p>

<h3 id="how-to-check-if-a-variable-is-an-array">How to check if a variable is an array?</h3>

<p>Try running this code:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">index 20</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">me</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">JavaScript Lover</span><span class="dl">'</span><span class="p">;</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Trust me, man, I'm an Array @@</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Really, I have to check your DNA.</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">JavaScript checker: arr is </span><span class="dl">'</span> <span class="o">+</span> <span class="k">typeof</span> <span class="nx">arr</span><span class="p">);</span>
</code></pre></div></div>

<p>??? You’re an Object, why do you claim to be an Array?
No, I’m an array — check with this tool:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">arr</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">index 20</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">arr</span><span class="p">[</span><span class="dl">'</span><span class="s1">me</span><span class="dl">'</span><span class="p">]</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">JavaScript Lover</span><span class="dl">'</span><span class="p">;</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span>
  <span class="dl">'</span><span class="s1">JavaScript checker: Is arr an array ... </span><span class="dl">'</span> <span class="o">+</span>
    <span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">toString</span><span class="p">.</span><span class="nf">apply</span><span class="p">(</span><span class="nx">arr</span><span class="p">)</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">[object Array]</span><span class="dl">'</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<p>Oh, oh, monkey — how can that be? See, I’m of royal descent, so I must hide my true identity. Spotting a pretty girl is easy, but telling a good one from a bad one takes real skill.</p>

<p>To wrap up, here’s a small piece of code for Node.js beginners. The task: fetch the contents of 3 web pages (HTTP) with addresses from command-line arguments asynchronously and print the page contents in the same order as the input arguments. You’ll see its connection to the array topics discussed above.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">http</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">http</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">bl</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">bl</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">var</span> <span class="nx">counter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="kd">function</span> <span class="nf">printData</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">for </span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">data</span><span class="p">[</span><span class="nx">i</span><span class="p">]);</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nf">loadData</span><span class="p">(</span><span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">http</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span> <span class="o">+</span> <span class="nx">index</span><span class="p">],</span> <span class="nf">function </span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">resp</span><span class="p">.</span><span class="nf">pipe</span><span class="p">(</span>
      <span class="nf">bl</span><span class="p">(</span><span class="nf">function </span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">buf</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="nx">data</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span> <span class="o">=</span> <span class="nx">err</span><span class="p">.</span><span class="nf">toString</span><span class="p">();</span>
        <span class="k">else</span> <span class="nx">data</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span> <span class="o">=</span> <span class="nx">buf</span><span class="p">.</span><span class="nf">toString</span><span class="p">();</span>
        <span class="nx">counter</span><span class="o">++</span><span class="p">;</span>
        <span class="k">if </span><span class="p">(</span><span class="nx">counter</span> <span class="o">===</span> <span class="mi">3</span><span class="p">)</span> <span class="nf">printData</span><span class="p">();</span>
      <span class="p">})</span>
    <span class="p">);</span>
  <span class="p">});</span>
<span class="p">}</span>

<span class="k">for </span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="nf">loadData</span><span class="p">(</span><span class="nx">i</span><span class="p">);</span>
</code></pre></div></div>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="javascript" /><category term="array" /><summary type="html"><![CDATA[Discover surprising array behaviors in JavaScript: `length` doesn't count actual elements, `for in` vs `forEach`, and how to check array type.]]></summary></entry><entry xml:lang="en"><title type="html">Functional Programming - Part 3 - Letting Go</title><link href="https://duclvz.github.io/en/posts/functional-programming-part-3-letting-go" rel="alternate" type="text/html" title="Functional Programming - Part 3 - Letting Go" /><published>2018-06-20T15:46:00+00:00</published><updated>2026-04-27T00:00:00+00:00</updated><id>https://duclvz.github.io/posts/functional-programming-part-3-letting-go</id><content type="html" xml:base="https://duclvz.github.io/posts/functional-programming-part-3-letting-go"><![CDATA[<blockquote>
  <p><strong>Style note:</strong> This series uses martial-arts/cultivation metaphors to tell the story of programming. This is an intentional choice by the author to make dry concepts more vivid.</p>
</blockquote>

<p>Functional Programming is a different path, a different way of thinking in coding. At a more abstract level, Functional Programming is categorized as “Declarative,” while OOP falls under “Imperative.”</p>

<p>From grammar lessons, we know two sentence types: Declarative Sentences and Imperative Sentences.</p>

<p>Programming in the “Imperative” style means arranging a series of sequential commands for the computer to execute step by step. Here the focus is on “how.” Do this, then do that… A form of “hand-holding instruction.”</p>

<p>For example, a web page has 4 red boxes like this:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;style&gt;</span>
<span class="nc">.box</span> <span class="p">{</span> <span class="nl">width</span><span class="p">:</span> <span class="m">100px</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span> <span class="m">100px</span><span class="p">;</span> <span class="nl">float</span><span class="p">:</span> <span class="nb">left</span><span class="p">;</span> <span class="nl">margin</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span> <span class="nl">background-color</span><span class="p">:</span> <span class="nx">red</span><span class="p">;</span> <span class="p">}</span>
<span class="nc">.hide</span> <span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span> <span class="p">}</span>
<span class="nt">&lt;/style&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"box hide"</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"box hide"</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"box hide"</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"box hide"</span><span class="nt">&gt;&lt;/div&gt;</span>
</code></pre></div></div>

<p>These boxes are hidden — we need to make them visible by removing the “hide” class.</p>

<p>The honorable computer science teachers of old used to teach writing it like this:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">els</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelectorAll</span><span class="p">(</span><span class="dl">'</span><span class="s1">.box</span><span class="dl">'</span><span class="p">);</span>
<span class="k">for </span><span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">els</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">el</span> <span class="o">=</span> <span class="nx">els</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
  <span class="nx">el</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">remove</span><span class="p">(</span><span class="dl">'</span><span class="s1">hide</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>They use code to instruct the computer to perform each task.</p>

<p>Functional Programming cultivators don’t think that way.</p>

<h3 id="no-forwhile">No for/while</h3>

<p>“Declarative Programming” focuses on “what.” We just need to define input and output rules. For instance, “if input is 1, output is 2.” The rest is for the computer to handle.</p>

<p>Functional Programming cultivators don’t need for loops.</p>

<p>Code like this looks much fresher:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">getElements</span> <span class="o">=</span> <span class="p">(</span><span class="nx">selector</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nb">Array</span><span class="p">.</span><span class="k">from</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nf">querySelectorAll</span><span class="p">(</span><span class="nx">selector</span><span class="p">));</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">getRemover</span> <span class="o">=</span> <span class="p">(</span><span class="nx">el</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return </span><span class="p">(</span><span class="nx">className</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">el</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nf">remove</span><span class="p">(</span><span class="nx">className</span><span class="p">);</span>
    <span class="k">return</span> <span class="nx">el</span><span class="p">;</span>
  <span class="p">};</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">els</span> <span class="o">=</span> <span class="nf">getElements</span><span class="p">(</span><span class="dl">'</span><span class="s1">.box</span><span class="dl">'</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="nx">getRemover</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">removeClass</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">removeClass</span><span class="p">(</span><span class="dl">'</span><span class="s1">hide</span><span class="dl">'</span><span class="p">));</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">els</span><span class="p">);</span>
</code></pre></div></div>

<p>First we create a pure function <code class="language-plaintext highlighter-rouge">getElements</code> to retrieve elements on the page via CSS Selector. This collection is ArrayLike — we use <code class="language-plaintext highlighter-rouge">Array.from</code> to convert it to a real Array so we can leverage Array prototype methods.</p>

<p>Here we define input as CSS Selector, output as an array of DOM Elements.</p>

<p><code class="language-plaintext highlighter-rouge">getRemover</code> is a higher-order function. We can call it by chaining <code class="language-plaintext highlighter-rouge">getRemover(DOMElement)(classToRemove)</code>. By leveraging the characteristics of higher-order functions, after two maps, we reach the function returned by <code class="language-plaintext highlighter-rouge">getRemover</code>.</p>

<p>Here we define input as DOM Element, output as <code class="language-plaintext highlighter-rouge">function() {takes className as input and returns the DOM Element without that class}</code>.</p>

<p>With code like this, we can reuse the logic in many places — just change the input. For example, removing the <code class="language-plaintext highlighter-rouge">float-left</code> class from all <code class="language-plaintext highlighter-rouge">div</code> elements:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">els</span> <span class="o">=</span> <span class="nf">getElements</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="nx">getRemover</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">removeClass</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">removeClass</span><span class="p">(</span><span class="dl">'</span><span class="s1">float-left</span><span class="dl">'</span><span class="p">));</span>
</code></pre></div></div>

<h3 id="no-ifelse">No if/else</h3>

<p>Functional Programming cultivators also don’t need if/else.</p>

<p>They’ve even created an entire Anti-IF campaign!</p>

<p>There are many ways to completely eliminate if/else from your program. The simplest is using ternary.</p>

<h4 id="ternary">Ternary</h4>

<p>In JavaScript, ternary — the Conditional Operator — is a concise way to write if/else.</p>

<p>Look at this verbose, complex branching code:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">title</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Mr.</span><span class="dl">'</span><span class="p">;</span>
<span class="k">if </span><span class="p">(</span><span class="nx">person</span><span class="p">.</span><span class="nx">gender</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">female</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="nx">person</span><span class="p">.</span><span class="nx">gotMarried</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">title</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Ms.</span><span class="dl">'</span><span class="p">;</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nx">title</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Mrs.</span><span class="dl">'</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>It can be condensed to:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">title</span> <span class="o">=</span>
  <span class="nx">person</span><span class="p">.</span><span class="nx">gender</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">female</span><span class="dl">'</span> <span class="p">?</span> <span class="p">(</span><span class="o">!</span><span class="nx">person</span><span class="p">.</span><span class="nx">gotMarried</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">Ms.</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">Mrs.</span><span class="dl">'</span><span class="p">)</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">Mr.</span><span class="dl">'</span><span class="p">;</span>
</code></pre></div></div>

<p>No more if/else.</p>

<p>We’ve also implicitly eliminated <code class="language-plaintext highlighter-rouge">var</code> and <code class="language-plaintext highlighter-rouge">let</code> because we no longer need to reassign <code class="language-plaintext highlighter-rouge">title</code>.</p>

<h4 id="logical-operators">Logical operators</h4>

<p>The second way is to exploit the hidden power of logical operators <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> and <code class="language-plaintext highlighter-rouge">||</code>.</p>

<p>Suppose we have this code:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">sayHello</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Hello, bonjour, nihao</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">doNothing</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Do nothing</span><span class="dl">'</span><span class="p">);</span>
  <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">greet</span> <span class="o">=</span> <span class="p">(</span><span class="nx">hasClient</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">hasClient</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">sayHello</span><span class="p">();</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="nf">doNothing</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">};</span>

<span class="nf">greet</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span> <span class="c1">// =&gt; 'Hello, bonjour, nihao'</span>
<span class="nf">greet</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span> <span class="c1">//=&gt; 'Do nothing'</span>
</code></pre></div></div>

<p>Logically, <code class="language-plaintext highlighter-rouge">greet()</code> checks: if there’s a client, greet them; otherwise, do nothing.</p>

<p>By the definitions of <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> and <code class="language-plaintext highlighter-rouge">||</code>, we know:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">expr1 &amp;&amp; expr2</code> returns <code class="language-plaintext highlighter-rouge">expr1</code> if <code class="language-plaintext highlighter-rouge">expr1</code> is falsy; otherwise, it returns <code class="language-plaintext highlighter-rouge">expr2</code>.</li>
</ul>

<p>An interesting thing here is that the JavaScript engine always evaluates logical expressions from left to right following the principle of “short-circuit evaluation.” Physics students might remember “short circuit” — when current doesn’t flow through the load or only flows through part of it.</p>

<p>Since AND only returns true if both operands are true, as soon as it encounters a false expr1, it immediately concludes the compound statement is False and stops there — never running expr2.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">expr1 || expr2</code> returns <code class="language-plaintext highlighter-rouge">expr1</code> if <code class="language-plaintext highlighter-rouge">expr1</code> is truthy; otherwise, it returns <code class="language-plaintext highlighter-rouge">expr2</code>.</li>
</ul>

<p>Since OR returns true if at least one operand is true, as soon as it encounters a true expr1, it immediately concludes the compound statement is True and skips expr2.</p>

<p>Short-circuit is divine!</p>

<p>Experienced developers often exploit this to optimize performance. They place complex computation expressions in the second half of a logical expression. This way, when the appropriate conditions aren’t met, they’re skipped — no resources wasted.</p>

<p>Now we can rewrite <code class="language-plaintext highlighter-rouge">greet()</code> in a cryptic way:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">greet</span> <span class="o">=</span> <span class="p">(</span><span class="nx">hasClient</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return </span><span class="p">(</span><span class="nx">hasClient</span> <span class="o">||</span> <span class="nf">doNothing</span><span class="p">())</span> <span class="o">&amp;&amp;</span> <span class="nf">sayHello</span><span class="p">();</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Start with the part in parentheses on the left of <code class="language-plaintext highlighter-rouge">&amp;&amp;</code>. If <code class="language-plaintext highlighter-rouge">hasClient</code> is truthy, this part’s value is <code class="language-plaintext highlighter-rouge">hasClient</code>, and <code class="language-plaintext highlighter-rouge">doNothing()</code> is skipped.</p>

<p>Since the left side of <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> is truthy, the expression’s final value reduces to the right side of <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> — <code class="language-plaintext highlighter-rouge">sayHello()</code>.</p>

<p>The same reasoning applies when <code class="language-plaintext highlighter-rouge">hasClient</code> is falsy — the flow immediately branches to <code class="language-plaintext highlighter-rouge">doNothing()</code>. At this point, the left side of <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> is falsy, so <code class="language-plaintext highlighter-rouge">sayHello()</code> is irrelevant.</p>

<p>Writing this way is both unique and novel, eliminates if/else, and perfectly matches the conditional logic.</p>

<p>However, logical operators can be hard to follow if you’re not used to them. I’m only showing this for reference. In actual projects, stick with ternary to spare your teammates’ brains:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">greet</span> <span class="o">=</span> <span class="p">(</span><span class="nx">hasClient</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">hasClient</span> <span class="p">?</span> <span class="nf">sayHello</span><span class="p">()</span> <span class="p">:</span> <span class="nf">doNothing</span><span class="p">();</span>
<span class="p">};</span>
</code></pre></div></div>

<h4 id="logical-functions">Logical functions</h4>

<p>Another approach expressing a more radical Functional Programming spirit is creating functions specifically responsible for logic handling. For example, Ramda.js and Sanctuary both have <code class="language-plaintext highlighter-rouge">ifElse</code>, <code class="language-plaintext highlighter-rouge">unless</code>, <code class="language-plaintext highlighter-rouge">when</code>, and dozens of other logic functions.</p>

<p>The <code class="language-plaintext highlighter-rouge">greet</code> function rewritten with Ramda becomes this lovely:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">R</span> <span class="o">=</span> <span class="nf">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">ramda</span><span class="dl">'</span><span class="p">);</span>

<span class="kd">const</span> <span class="nx">greet</span> <span class="o">=</span> <span class="nx">R</span><span class="p">.</span><span class="nf">ifElse</span><span class="p">(</span><span class="nx">R</span><span class="p">.</span><span class="nx">identity</span><span class="p">,</span> <span class="nx">sayHello</span><span class="p">,</span> <span class="nx">doNothing</span><span class="p">);</span>
</code></pre></div></div>

<p>That’s the artistic beauty of Function Composition. Just gaze at it and say nothing! Composition also means a creative work — like Paul Verlaine’s poetry or Beethoven’s music.</p>

<h3 id="no-newthis">No new/this</h3>

<p>There are two things that always make Brendan Eich satisfied when telling JavaScript’s history: first-class functions and the prototype mechanism.</p>

<p>Today, most developers know that inheritance in JavaScript is prototype-based. But in the web’s early days, people commonly used <code class="language-plaintext highlighter-rouge">new</code> and constructor functions to do OOP in JavaScript in a class-based style, similar to Java.</p>

<h4 id="classical-inheritance">Classical inheritance</h4>

<p>Ancient texts record many examples like this:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">Dog</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span>
  <span class="k">this</span><span class="p">.</span><span class="nx">say</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">woof-woof, my name is </span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">);</span>
  <span class="p">};</span>
<span class="p">}</span>

<span class="kd">var</span> <span class="nx">rocky</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Dog</span><span class="p">(</span><span class="dl">'</span><span class="s1">Rocky</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">rocky</span><span class="p">.</span><span class="nf">say</span><span class="p">();</span>

<span class="kd">var</span> <span class="nx">molly</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Dog</span><span class="p">(</span><span class="dl">'</span><span class="s1">Molly</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">molly</span><span class="p">.</span><span class="nf">say</span><span class="p">();</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">Dog</code> function is called a Function Constructor. Early Đại Việt cultivators translated it as “hàm dựng.”</p>

<h4 id="prototypal-inheritance">Prototypal inheritance</h4>

<p>At the start of the 3rd millennium, at the Yahoo! sect, a deeply cultivated elder named Douglas Crockford released the extraordinary book “JavaScript: The Good Parts,” emphasizing JavaScript’s prototype nature and the difference between classical and prototypal inheritance. He argued that the <code class="language-plaintext highlighter-rouge">new</code> keyword carries many drawbacks and encouraged using <code class="language-plaintext highlighter-rouge">Object.create</code> to copy prototypes to inheriting objects.</p>

<p>Douglas Crockford’s thinking was truly fresh. At the time, many JavaScript engines hadn’t yet supported <code class="language-plaintext highlighter-rouge">Object.create</code>. This book stirred up the entire programming world upon release, becoming the bedside book of countless cultivators.</p>

<p><code class="language-plaintext highlighter-rouge">Object.create</code> allows copying an object’s properties or prototype. The <code class="language-plaintext highlighter-rouge">Dog</code> function can be rewritten in a prototypal inheritance style:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">Dog</span><span class="p">()</span> <span class="p">{}</span>

<span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">say</span> <span class="o">=</span> <span class="nf">function </span><span class="p">()</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">woof-woof, my name is </span><span class="dl">'</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">);</span>
<span class="p">};</span>

<span class="kd">var</span> <span class="nx">rocky</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span><span class="p">);</span>
<span class="nx">rocky</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Rocky</span><span class="dl">'</span><span class="p">;</span>

<span class="kd">var</span> <span class="nx">molly</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="nx">Dog</span><span class="p">.</span><span class="nx">prototype</span><span class="p">);</span>
<span class="nx">molly</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Molly</span><span class="dl">'</span><span class="p">;</span>

<span class="nx">rocky</span><span class="p">.</span><span class="nf">say</span><span class="p">();</span>
<span class="nx">molly</span><span class="p">.</span><span class="nf">say</span><span class="p">();</span>
</code></pre></div></div>

<p>No more <code class="language-plaintext highlighter-rouge">new</code>!</p>

<p>Subsequent masters quickly developed many other prototypal inheritance approaches, most notably Concatenative inheritance, Prototype delegation, and Functional inheritance.</p>

<p>ES6 Class today only borrows classical OOP syntax as an interface — internally, it’s the prototypal inheritance mechanism.</p>

<h4 id="object-composition">Object Composition</h4>

<p>But prototypal inheritance still belongs to OOP.</p>

<p>Functional Programming cultivators don’t need <code class="language-plaintext highlighter-rouge">new</code>.</p>

<p>Nearly 10 years after the bombshell “The Good Parts,” Douglas Crockford once again shook the programming world with “JavaScript: The Better Parts.” By this point, he no longer used <code class="language-plaintext highlighter-rouge">Object.create()</code>, and had also abandoned <code class="language-plaintext highlighter-rouge">this</code>, <code class="language-plaintext highlighter-rouge">for</code> loops, <code class="language-plaintext highlighter-rouge">for in</code>, <code class="language-plaintext highlighter-rouge">while</code>… His cultivation had taken another major step. In the talk, he discussed new ES6 features that hadn’t yet officially shipped. These grandmaster types are always years ahead of everyone else.</p>

<YouTube id="bo36MrBfTk4" />

<p>That was also when the Functional Programming trend was heating up again, and people began talking about Object Composition.</p>

<p>Paired with <code class="language-plaintext highlighter-rouge">new</code> is <code class="language-plaintext highlighter-rouge">this</code>. The <code class="language-plaintext highlighter-rouge">this</code> keyword is merely a trick to create an isolated context for executing functions. In JavaScript, each function is like an independent barrier. When a function is attached to an object, it’s called a method. The context in which that method runs is usually the object that owns it. Later came the techniques <code class="language-plaintext highlighter-rouge">bind</code>, <code class="language-plaintext highlighter-rouge">apply</code>, <code class="language-plaintext highlighter-rouge">call</code> to swap contexts.</p>

<p>For JavaScript newcomers, <code class="language-plaintext highlighter-rouge">this</code> sometimes becomes a terror. It’s very hard to debug issues in a function without knowing its exact execution context. And the context is usually unstable — or rather, it’s always mutable.</p>

<p>Functional Programming cultivators don’t need <code class="language-plaintext highlighter-rouge">this</code>.</p>

<p>The classical OOP code above can be rewritten as:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">sayName</span> <span class="o">=</span> <span class="p">(</span><span class="nx">state</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nf">assign</span><span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">say</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`woof-woof, my name is </span><span class="p">${</span><span class="nx">state</span><span class="p">.</span><span class="nx">name</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
    <span class="p">},</span>
  <span class="p">});</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">createDog</span> <span class="o">=</span> <span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">let</span> <span class="nx">state</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">name</span> <span class="p">};</span>
  <span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nf">assign</span><span class="p">(</span><span class="nx">state</span><span class="p">,</span> <span class="nf">sayName</span><span class="p">(</span><span class="nx">state</span><span class="p">));</span>
<span class="p">};</span>

<span class="kd">const</span> <span class="nx">rocky</span> <span class="o">=</span> <span class="nf">createDog</span><span class="p">(</span><span class="dl">'</span><span class="s1">Rocky</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">rocky</span><span class="p">.</span><span class="nf">say</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">molly</span> <span class="o">=</span> <span class="nf">createDog</span><span class="p">(</span><span class="dl">'</span><span class="s1">Molly</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">molly</span><span class="p">.</span><span class="nf">say</span><span class="p">();</span>
</code></pre></div></div>

<p>Everywhere you look, you see functions.</p>

<p>No more for/while, if/else, new/this.</p>

<p>Are you ready to leave behind those mundane things?</p>

<p>Or as the monks say, can you let go?</p>

<p><img src="https://i.imgur.com/LK0k8LW.jpg" alt="Meditating monk — symbol of letting go" /></p>

<p>When traditional thinking has sunk deep into your mind, whenever you face an object hierarchy problem, you immediately think of OOP, class, prototype, inheritance… even treating them as the inevitable, only solution. Whenever you process collections, you loop. Whenever you see conditions, you rely on if… This is a huge obstacle for newcomers to the path.</p>

<p>You must find a way to shed what’s unnecessary, or you won’t go far.</p>

<p>Leave them behind, holding only one notion: FUNCTION!</p>

<p>One thought: “function”!</p>

<p><img src="https://i.imgur.com/0clmtSN.jpg" alt="Bodhidharma — one thought: &quot;function&quot;" /></p>

<p>At first, it will naturally be difficult and awkward. Like how every day you walk the familiar road from home to office and back. Until one day that road is blocked by police, and you must take a detour.</p>

<p>On that unfamiliar road, you no longer see the landmarks you’ve seen every day: a souvenir shop, a gas station, a pawn shop, after the intersection comes the riverside, the red-painted bridge, a grocery store where a very pretty girl usually sits out front… You no longer encounter those familiar signs. You don’t know where you are, how many kilometers remain to home.</p>

<p>But any road becomes familiar after a few trips. Nothing to worry about. The point is, as soon as you recognize Functional Programming as something fascinating and worth learning and applying, you should start immediately — don’t wait for a convenient moment, don’t wait to find a master to guide you. If you do, you’ll struggle to leave the old ruts.</p>

<p>Krishnamurti once expressed something similar, roughly:</p>

<blockquote>
  <p>If you’ve been heading North all the days of your life, as humanity has followed a particular direction, and then someone appears and says, “That direction is not right.” Then they tell you, “Go South, East, any direction except that one.” And when you actually move away from that direction, there is a change right at the level of the brain cells because you’ve broken the pattern. And that pattern must be broken right now — not forty years or a hundred years from now.</p>
</blockquote>

<hr />

<blockquote>
  <p><strong>Read more:</strong> If you want a more systematic and direct approach to FP, check out the series <a href="/en/posts/tro-thanh-functional-programmer-phan-1">Becoming a Functional Programmer</a> — a translation of Charles Scalfani’s famous series, also on this blog.</p>
</blockquote>]]></content><author><name>Duc Lv</name></author><category term="posts" /><category term="javascript" /><category term="functional-programming" /><summary type="html"><![CDATA[Letting go of for/while, if/else, new/this — the habits of Imperative Programming — to step into the pure world of Functional Programming.]]></summary></entry></feed>