<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://www.frontendinterviewhandbook.com/zh-CN/blog</id>
    <title>The Official Front End Interview Handbook 2026 Blog</title>
    <updated>2022-06-18T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://www.frontendinterviewhandbook.com/zh-CN/blog"/>
    <subtitle>The Official Front End Interview Handbook 2026 Blog</subtitle>
    <icon>https://www.frontendinterviewhandbook.com/zh-CN/img/favicon.png</icon>
    <entry>
        <title type="html"><![CDATA[When You Should Prefer Map Over Object In JavaScript]]></title>
        <id>https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map</id>
        <link href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map"/>
        <updated>2022-06-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[See discussions on Reddit]]></summary>
        <content type="html"><![CDATA[
<blockquote>
<p>See discussions on <a href="https://www.reddit.com/r/javascript/comments/vgs7y1/why_you_should_prefer_map_over_object_in/" target="_blank" rel="noopener noreferrer">Reddit</a></p>
</blockquote>
<p>In JavaScript, objects are handy. They allow us to easily group multiple pieces of data together. After ES6, we got a new addition to the language - <code>Map</code>. In a lot of aspects, it seems like a more capable <code>Object</code> with a somewhat clumsy interface. However, most people still reach for objects when they need a <a href="https://en.wikipedia.org/wiki/Hash_table" target="_blank" rel="noopener noreferrer">hash map</a> and only switch to using <code>Map</code> when they realize the keys can't just be strings for their use cases. As a result, <code>Map</code> remains <strong>underused</strong> in today's JavaScript community.</p>
<p>In this post, I will break down all the reasons when you should consider using <code>Map</code> more and its performance characteristics with benchmarks.</p>
<blockquote>
<p>In JavaScript, Object is a pretty broad term. Almost everything can be an object, except for two bottom types - <code>null</code> and <code>undefined</code>. In this blog post, Object only refers to plain old objects, delimited by a left brace <code>{</code> and a right brace <code>}</code>.</p>
</blockquote>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="tldr">TL;DR:<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#tldr" class="hash-link" aria-label="TL;DR:的直接链接" title="TL;DR:的直接链接">​</a></h2>
<ul>
<li>Use <code>Object</code> for records where you have a fixed and finite number of properties/fields known at author time, such as a config object. And anything that is for one-time use in general.</li>
<li>Use <code>Map</code> for dictionaries or hash maps where you have a variable number of entries, with frequent updates, whose keys might not be known at author time, such as an <a href="https://github.com/developit/mitt/blob/main/src/index.ts#L45" target="_blank" rel="noopener noreferrer">event emitter</a>.</li>
<li>According to <a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#performance-extravaganza">my benchmarks</a>, <em>unless</em> the keys are strings of small integers, <code>Map</code> is indeed <strong>more performant</strong> than <code>Object</code> on insertion, deletion and iteration speed, and it consumes <strong>less memory</strong> than an object of the same size.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="why-object-falls-short-of-a-hash-map-use-case">Why <code>Object</code> falls short of a hash map use case<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#why-object-falls-short-of-a-hash-map-use-case" class="hash-link" aria-label="why-object-falls-short-of-a-hash-map-use-case的直接链接" title="why-object-falls-short-of-a-hash-map-use-case的直接链接">​</a></h2>
<p>Probably the most obvious downside of using objects for hash maps is that objects only allow keys that are strings and symbols. Any other types will be implicitly cast to string via the <code>toString</code> method.</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> foo </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> bar </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> obj </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">foo</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">bar</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// {"": 'foo', [object Object]: 'bar'}</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>More importantly, using objects for hash maps can cause confusion and <em>security hazards</em>.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="unwanted-inheritance">Unwanted inheritance<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#unwanted-inheritance" class="hash-link" aria-label="Unwanted inheritance的直接链接" title="Unwanted inheritance的直接链接">​</a></h3>
<p>Before ES6, the only way to get a hash map is by creating an empty object.</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> hashMap </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>However, upon creation, this object is no longer empty. Although <code>hashMap</code> is made with an empty object literal, it automatically inherits from <code>Object.prototype</code>. That's why we can invoke methods like <code>hasOwnProperty</code>, <code>toString</code>, <code>constructor</code> on <code>hashMap</code> even though we never explicitly defined those methods on the object.</p>
<p>Because of prototypal inheritance, we now have two types of properties conflated: properties that live within the object itself, i.e. its <em>own</em> properties, and properties that live in the prototype chain, i.e. <em>inherited</em> properties. As a result, we need an additional check (e.g. <code>hasOwnProperty</code>) to make sure a given property is indeed user-provided, as opposed to inherited from the prototype.</p>
<p>On top of that, because of how the property resolution mechanism works in JavaScript, any change to <code>Object.prototype</code> at runtime will cause a <em>ripple</em> effect in all objects. This opens the door for <a href="https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf" target="_blank" rel="noopener noreferrer">prototype pollution attacks</a>, which can be a serious security issue for large JavaScript applications.</p>
<p>Fortunately, we can work around this by using <code>Object.create(null)</code>, which makes an object that inherits nothing from <code>Object.prototype</code>.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="name-collisions">Name collisions<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#name-collisions" class="hash-link" aria-label="Name collisions的直接链接" title="Name collisions的直接链接">​</a></h3>
<p>When an object's <em>own</em> properties have name collisions with ones on its prototype, it breaks expectations and thus crashes your program.</p>
<p>For example, we have a function <code>foo</code> which accepts an object:</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">obj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> key </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> obj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">hasOwnProperty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>There is a reliability hazard in <code>obj.hasOwnProperty(key)</code>: given how property resolution mechanism works in JavaScript, if <code>obj</code> contains a user-provided property with the same name <code>hasOwnProperty</code>, that shadows <code>Object.prototype.hasOwnProperty</code>. As a result, we <em>don't know</em> which method is going to get called exactly during runtime.</p>
<p>Some defensive programming can be done to prevent this. For example we can "borrow" the "real" <code>hasOwnProperty</code> from <code>Object.prototype</code> instead:</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">obj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">//...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> key </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> obj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">prototype</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">hasOwnProperty</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">call</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>A shorter way might be invoking the method on an object literal as in <code>{}.hasOwnProperty.call(key)</code> however it is still pretty cumbersome. That's why there is a newly-added static method <code>Object.hasOwn</code>.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="sub-optimal-ergonomics">Sub-optimal ergonomics<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#sub-optimal-ergonomics" class="hash-link" aria-label="Sub-optimal ergonomics的直接链接" title="Sub-optimal ergonomics的直接链接">​</a></h3>
<p><code>Object</code> doesn't provide adequate ergonomics to be used as a hash map. Many common tasks can't be intuitively performed.</p>
<h4 class="anchor anchorWithStickyNavbar_LSVY" id="size">size<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#size" class="hash-link" aria-label="size的直接链接" title="size的直接链接">​</a></h4>
<p><code>Object</code> doesn't come with a handy API to get the size, i.e. the number of properties. And there are nuances to what constitutes the size of an object:</p>
<ul>
<li>if you only care about string, enumerable keys, then you can convert the keys to an array with <code>Object.keys()</code> and get its <code>length</code>.</li>
<li>if you want to account for <em>non-enumerable</em> string keys, then you have to use <code>Object.getOwnPropertyNames</code> to get a list of the keys and get its length.</li>
<li>if you are interested in symbol keys, you can use <code>getOwnPropertySymbols</code> to reveal the symbol keys. Or you can use <code>Reflect.ownKeys</code> to get both string keys and symbol keys all at once, regardless if it is enumerable or not.</li>
</ul>
<p>All the above options take a runtime complexity of <code>O(n)</code> since we have to construct an array of keys first before we can get its length.</p>
<h4 class="anchor anchorWithStickyNavbar_LSVY" id="iterate">iterate<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#iterate" class="hash-link" aria-label="iterate的直接链接" title="iterate的直接链接">​</a></h4>
<p>Looping through objects suffers from similar complexity.</p>
<p>We can use the good old <code>for ... in</code> loop. But it reveals inherited enumerable properties:</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token class-name">Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">prototype</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">foo</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> obj </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> key </span><span class="token keyword" style="color:#00009f">in</span><span class="token plain"> obj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">key</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 'id', 'foo'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>We can't use <code>for ... of</code> with an object since by default it is not an iterable, unless we explicitly define the <code>Symbol.iterator</code> method on it.</p>
<p>We can use <code>Object.keys</code>, <code>Object.values</code> and <code>Object.entries</code> to get a list of enumerable, string keys (or/and values) and iterate through that instead, which introduces an extra step with overhead.</p>
<p>Finally, the insertion order is infamously not <em>fully</em> respected. In most browsers, integer keys are sorted in ascending order and take precedence over string keys even if the string keys were inserted before the integer keys.</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> obj </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">foo</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'first'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'second'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'last'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// {1: 'last', 2: 'second', foo: 'first'}</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithStickyNavbar_LSVY" id="clear">clear<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#clear" class="hash-link" aria-label="clear的直接链接" title="clear的直接链接">​</a></h4>
<p>There is no easy way to remove all properties from an object, you have to delete each property one by one with the <code>delete</code> operator, which <a href="https://stackoverflow.com/questions/43594092/slow-delete-of-object-properties-in-js-in-v8" target="_blank" rel="noopener noreferrer">has been historically known</a> to be slow. However, my benchmarks show that its performance is actually not an order-of-magnitude slower than <code>Map.prototype.delete</code>. More on that later.</p>
<h4 class="anchor anchorWithStickyNavbar_LSVY" id="check-property-existence">check property existence<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#check-property-existence" class="hash-link" aria-label="check property existence的直接链接" title="check property existence的直接链接">​</a></h4>
<p>Finally, we can't rely on the dot/bracket notation to check for the existence of a property because the value itself could be set as <code>undefined</code>. Instead we have to use <code>Object.prototype.hasOwnProperty</code> or <code>Object.hasOwn</code>.</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> obj </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">a</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword nil" style="color:#00009f">undefined</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token known-class-name class-name">Object</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">hasOwn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">obj</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'a'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// true</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="map-for-hash-map">Map for Hash Map<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#map-for-hash-map" class="hash-link" aria-label="Map for Hash Map的直接链接" title="Map for Hash Map的直接链接">​</a></h2>
<p>ES6 brings us <code>Map</code>. It is much more suited for a hash map use case.</p>
<p>First of all, unlike <code>Object</code>, which only allows keys that are strings and symbols, <code>Map</code> supports keys of any data type.</p>
<blockquote>
<p>However if you are using <code>Map</code> to store meta-data for objects, then you should use <code>WeakMap</code> instead to avoid memory leak.</p>
</blockquote>
<p>But more importantly, <code>Map</code> provides a <em>clean separation</em> between user-defined and built-in program data, at the expense of an additional <code>Map.prototype.get</code> to retrieve entries.</p>
<p><code>Map</code> also provides better ergonomics: A <code>Map</code> is an iterable by default. That means you can iterate a map easily with <code>for ... of</code>, and do things like using nested destructuring to pull out the first entry from a map.</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">firstKey</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> firstValue</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> map</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>In contrast to <code>Object</code>, <code>Map</code> provides dedicated APIs for various common tasks:</p>
<ul>
<li><code>Map.prototype.has</code> checks for the existence of a given entry, less awkward compared to having to <code>Object.prototype.hasOwnProperty</code> / <code>Object.hasOwn</code> on objects.</li>
<li><code>Map.prototype.get</code> returns the value associated to the provided key. One might feel this is clunkier than the dot notation or the bracket notation on objects. Nevertheless it provides a clean separation between user data and built-in method.</li>
<li><code>Map.prototype.size</code> returns the number of entries in a <code>Map</code> and it is a clear winner over the maneuvers you have to perform to get an object's size. Besides, it is much faster.</li>
<li><code>Map.prototype.clear</code> removes all the entries in a <code>Map</code> and it is much faster than the <code>delete</code> operator.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="performance-extravaganza">Performance extravaganza<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#performance-extravaganza" class="hash-link" aria-label="Performance extravaganza的直接链接" title="Performance extravaganza的直接链接">​</a></h2>
<p>There seems to be a common belief among the JavaScript community that <code>Map</code> is faster than <code>Object</code>, for the most part. There are <a href="https://twitter.com/diegohaz/status/1534888291732013058" target="_blank" rel="noopener noreferrer">people</a> who claimed to see noticeable performance gains by switching from <code>Object</code> to <code>Map</code>.</p>
<p>My experience of grinding LeetCode seems to confirm this belief: LeetCode feeds a huge amount of data as the test cases to your solution and it times out if your solution is taking too long. Questions like <a href="https://leetcode.com/problems/random-pick-with-weight/solutions/671804/Javascript-with-explanation-and-very-interesting-find-regarding-vs-Map/" target="_blank" rel="noopener noreferrer">this</a> only time out if you use <code>Object</code>, but not <code>Map</code>.</p>
<p>However, I believe just saying "<code>Map</code> is faster than <code>Object</code>" is reductive. There must be some nuance that I wanted to find out myself. Therefore, I built <a href="https://csb-yuu1dm.netlify.app/" target="_blank" rel="noopener noreferrer">a little app</a> to run some benchmarks.</p>
<details class="details_DAfx alert alert--info details_VmYD" data-collapsed="true"><summary>Important Disclaimer</summary><div><div class="collapsibleContent_m550"><p>I don't claim to fully understand how V8 works under the hood to optimize <code>Map</code> despite my many attempts to read blog posts and peek into the C++ source code. Perfectly robust benchmarking is hard, and most of us have never gone through any form of training in either benchmarking or interpreting the results. The more benchmarking I do the more it felt like a story about <a href="https://en.wikipedia.org/wiki/Blind_men_and_an_elephant" target="_blank" rel="noopener noreferrer">blind men and an elephant</a>. So take everything I'm saying here about performance with a grain of salt. You'll need to test such changes with your application in a production environment to know for sure if there are actual performance gains from using <code>Map</code>s over <code>Object</code>s.</p></div></div></details>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="benchmarking-implementation-details">Benchmarking implementation details<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#benchmarking-implementation-details" class="hash-link" aria-label="Benchmarking implementation details的直接链接" title="Benchmarking implementation details的直接链接">​</a></h3>
<p><a href="https://csb-yuu1dm.netlify.app/" target="_blank" rel="noopener noreferrer">The app</a> has a table that shows the insertion, iteration, and deletion speed measured on <code>Object</code> and <code>Map</code>.</p>
<p>The performances of insertion and iteration are measured in operations per second. I wrote a utility function <code>measureFor</code> that runs the target function repeatedly until the specified minimal amount of time threshold (i.e. the <code>duration</code> input field on the UI) has been reached. It returns the average number of times such a function is executed per second.</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">measureFor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">f</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> duration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> iterations </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> now </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">performance</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> elapsed </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">while</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">elapsed </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> duration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    elapsed </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">performance</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">now</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> now</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    iterations</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">iterations </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> elapsed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toFixed</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>As for deletion, I am simply going to measure the time taken for using the <code>delete</code> operator to remove all properties from an object and compare it with the time with <code>Map.prototype.delete</code> for a <code>Map</code> of the same size. I could use <code>Map.prototype.clear</code> but it defeats the purpose of the benchmarks as I know for sure it is going to be vastly faster.</p>
<p>In these three operations, I pay more attention to insertion since it tends to be the most common operation I perform in my day-to-day work. For iteration performance, it is hard to come up with an all-encompassing benchmark as there are many different variants of iteration we can perform on a given object. Here I am only measuring the <code>for ... in</code> loop.</p>
<p>I used three types of keys here:</p>
<ol>
<li>strings, e.g. <code>yekwl7caqejth7aawelo4</code>.</li>
<li>integer strings, e.g. <code>123</code>.</li>
<li>numeric strings generated by <code>Math.random().toString()</code>, e.g. <code>0.4024025689756525</code>.</li>
</ol>
<p>All keys are randomly generated so we don't hit the inline-cache implemented by V8. I also explicitly convert integer and numeric keys to strings using <code>toString</code> before adding them to objects to avoid the overhead of implicitly casting.</p>
<p>Lastly, before the benchmark begins, there is also a warmup phase for at least 100ms where we repeatedly create new objects and maps that are discarded right away.</p>
<p>I put the code on <a href="https://codesandbox.io/s/still-glitter-yuu1dm" target="_blank" rel="noopener noreferrer">CodeSandbox</a> if you want to play with it.</p>
<p>I started with <code>Object</code> and <code>Map</code> with a size of 100 properties/entries, all the way to 5000000, and had each type of operations keep running for 10000ms to see how they performed against each other. Here are my findings...</p>
<details class="details_DAfx alert alert--info details_VmYD" data-collapsed="true"><summary>Why do we stop when the number of entries reaches 5000000?</summary><div><div class="collapsibleContent_m550"><p>Because this is about as big as an object can get in JavaScript. According to <a href="https://stackoverflow.com/questions/54452896/maximum-number-of-entries-in-node-js-map#comment127492362_72149605" target="_blank" rel="noopener noreferrer">@jmrk</a>, a V8 engineer who is active on StackOverflow, "if the keys are strings, a regular object becomes unusably slow after ~8.3M elements (for which there is a technical reason: a certain bit field being 23 bits wide and taking a very slow fallback path when exceeded).".</p></div></div></details>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="string-keys">string keys<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#string-keys" class="hash-link" aria-label="string keys的直接链接" title="string keys的直接链接">​</a></h3>
<p>Generally speaking, when keys are (non-numeric) strings, <code>Map</code> outperforms <code>Object</code> on all operations.</p>
<p><img decoding="async" loading="lazy" src="https://www.zhenghao.io/art/blog/object-vs-map/deletion-speed.png" alt="Map vs Object operations benchmark" class="img_gUYC"></p>
<p>But the nuance is that when the number of entries is not really huge (under 100000), <code>Map</code> is twice as fast as <code>Object</code> on insertion speed, but as the size grows over 100000, the performance gap starts to shrink.</p>
<p>I made some graphs to better illustrate my findings.</p>
<p><img decoding="async" loading="lazy" src="https://www.zhenghao.io/art/blog/object-vs-map/string-key-line-1.png" alt="Object vs Map insertion performance with string keys" class="img_gUYC"></p>
<p>The above graph shows how insertion rate drops (y-axis) as the number of entries increased (x-axis). However because the x-axis expands too wide (from 100 to 1000000), it is hard to tell the gap between these two lines.</p>
<p>I then used logarithmic scale to process the data and made the graph below.</p>
<p><img decoding="async" loading="lazy" src="https://www.zhenghao.io/art/blog/object-vs-map/string-key-line-2.png" alt="Object vs Map insertion performance with string keys on logarithmic scale" class="img_gUYC"></p>
<p>You can clearly tell the two lines are converging.</p>
<p>I made another graph plotting how much faster <code>Map</code> is in relation to <code>Object</code> on insertion speed. You can see <code>Map</code> starts out being about 2 times faster than <code>Object</code>. Then over time the performance gap starts to shrink. Eventually <code>Map</code> is only 30% faster as the size grows to 5000000.</p>
<p><img decoding="async" loading="lazy" src="https://www.zhenghao.io/art/blog/object-vs-map/string-key-line-3.png" alt="Object vs Map insertion relative performance on logarithmic scale" class="img_gUYC"></p>
<p>Most of us will never have more than 1 million entries in an object or map though. With a size of a few hundreds or thousands of entries, <code>Map</code> is at least twice as performant as <code>Object</code>. Therefore, should we leave it at that and head over to start refactoring our codebase by going all in on <code>Map</code>?</p>
<p>Absolutely not... or at least not with an expectation that our app becomes 2 times faster. Remember we haven't explored other types of keys. Let's take a look at integer keys.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="integer-keys">integer keys<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#integer-keys" class="hash-link" aria-label="integer keys的直接链接" title="integer keys的直接链接">​</a></h3>
<p>The reason I specifically want to run benchmarks on objects with integer keys is that V8 internally optimizes <a href="https://v8.dev/blog/fast-properties#named-properties-vs.-elements" target="_blank" rel="noopener noreferrer">integer-indexed properties</a> and store them in a separate array that can be accessed linearly and consecutively. I can't find any resources confirming it employs the same kind of optimization for <code>Map</code>s though.</p>
<p>Let's first try integer keys in the range of [0, 1000].</p>
<p><img decoding="async" loading="lazy" src="https://www.zhenghao.io/art/blog/object-vs-map/integer-key-1.png" alt="Object vs Map insertion performance with integer keys" class="img_gUYC"></p>
<p>As I expected, <code>Object</code> <strong>outperforms</strong> <code>Map</code> this time. They are 65% faster than maps for insertion speed and 16% faster to iterate.</p>
<p>Let's widen the range so that the maximum integer in the keys is 1200.</p>
<p><img decoding="async" loading="lazy" src="https://www.zhenghao.io/art/blog/object-vs-map/integer-key-2.png" alt="Object vs Map insertion performance with integer keys with maximum integer of 1200" class="img_gUYC"></p>
<p>It seems like now <code>Map</code> s are starting to get a little faster than objects for insertion and 5 times faster for iteration.</p>
<p>Note that we only increased the integer keys' range, not the actual size of <code>Object</code> and <code>Map</code>. Let's bump up the size to see how that affects the performances.</p>
<p><img decoding="async" loading="lazy" src="https://www.zhenghao.io/art/blog/object-vs-map/integer-key-3.png" alt="Object vs Map insertion performance with integer keys with 1000 properties" class="img_gUYC"></p>
<p>With a size of 1000 properties, <code>Object</code> ends up being 70% faster than <code>Map</code> for insertion and 2 times slower for iteration.</p>
<p>I played with a bunch of different combinations of <code>Object</code>/<code>Map</code> sizes and integer key ranges and failed to come up with a clear pattern. But the general trend I am seeing is that, for as the size grows, with some relatively small integer being the keys, objects can be <em>more performant</em> than <code>Map</code>s in terms of insertion, always roughly the same for deletion and 4 or 5 times slower to iterate. The threshold of max integer keys at which objects start to be slower for insertion grows with the size of the objects. For example, when the object only has 100 entries, the threshold is 1200; when it has 10000 entries, the threshold seems to be around 24000.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="numeric-keys">numeric keys<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#numeric-keys" class="hash-link" aria-label="numeric keys的直接链接" title="numeric keys的直接链接">​</a></h3>
<p>Lastly, let's take a look at the last type of keys - numeric keys.</p>
<p>Technically, the previously mentioned integer keys are also numeric. Here numeric keys specifically refer to the numeric strings generated by <code>Math.random().toString()</code>.</p>
<p>The results are similar to those string-key cases: <code>Map</code>s start off as much faster than objects (2 times faster for insertion and deletion, 4-5 times faster for iteration), but the delta is getting smaller as we increase the size.</p>
<details class="details_DAfx alert alert--info details_VmYD" data-collapsed="true"><summary>What about nested objects/maps?</summary><div><div class="collapsibleContent_m550"><p>You might have noticed that I have been only talking about flat objects and maps with only one depth. I did add some depth but I found the performance characteristics stay largely the same as long as the total number of entries is the same, no matter how many levels of nesting we have.</p><p>For example, with <code>width</code> being 100 and <code>depth</code> being 3, we have a total number of one million entries (100 * 100 * 100). The results are pretty much the same compared to just having <code>1000000</code> for width and 1 for <code>depth</code></p></div></div></details>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="memory-usage">Memory usage<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#memory-usage" class="hash-link" aria-label="Memory usage的直接链接" title="Memory usage的直接链接">​</a></h3>
<p>Another important facet of benchmarking is memory utilization.</p>
<p>Since I don't have control over the garbage collector in a browser environment, I decided to run benchmarks in Node.</p>
<p>I created a <a href="https://gist.github.com/zhenghaohe/b496dcffe3a9a6217eba90776dc2cafe" target="_blank" rel="noopener noreferrer">little script</a> to measure their respective memory usage with manually triggered full garbage collection in each measurement. Run it with <code>node --expose-gc</code> and I got the following results:</p>
<div class="language-jsx codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-jsx codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">object</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">'string-key'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'10000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3.390625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'50000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">19.765625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'100000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">16.265625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'500000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">71.265625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'1000000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">142.015625</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">'numeric-key'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'10000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1.65625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'50000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">8.265625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'100000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">16.765625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'500000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">72.265625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'1000000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">143.515625</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">'integer-key'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'10000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.25</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'50000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2.828125</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'100000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4.90625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'500000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">25.734375</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'1000000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">59.203125</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">map</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">'string-key'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'10000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1.703125</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'50000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">6.765625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'100000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">14.015625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'500000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">61.765625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'1000000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">122.015625</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">'numeric-key'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'10000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.703125</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'50000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3.765625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'100000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7.265625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'500000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">33.265625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'1000000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">67.015625</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string-property property" style="color:#36acaa">'integer-key'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'10000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.484375</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'50000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1.890625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'100000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3.765625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'500000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">22.515625</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token string-property property" style="color:#36acaa">'1000000'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">43.515625</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>It is pretty clear that <code>Map</code> consumes less memory than <code>Object</code> by anywhere from 20% to 50%, which is no surprise since <code>Map</code> doesn't store <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties" target="_blank" rel="noopener noreferrer">property descriptors</a> such as <code>writable</code>/<code>enumerable</code>/<code>configurable</code> like <code>Object</code> does.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="conclusion">Conclusion<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#conclusion" class="hash-link" aria-label="Conclusion的直接链接" title="Conclusion的直接链接">​</a></h2>
<p>So what do we take away from all this?</p>
<ul>
<li><code>Map</code> is faster than <code>Object</code> <em>unless</em> you have small integer, array-indexed keys, and it is more memory-efficient.</li>
<li>Use <code>Map</code> if you need a hash map with frequent updates; use <code>Object</code> if you want a fixed key-value collection (i.e. record), and watch out for pitfalls that come with prototypal inheritance.</li>
</ul>
<blockquote>
<p>If you know the details of exactly how V8 optimizes <code>Map</code> or simply want to call out the flaws in my benchmarks, ping me. I'll be happy to update this post based on your information!</p>
</blockquote>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="notes-on-browser-compatibility">Notes on browser compatibility<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/javascript-object-vs-map#notes-on-browser-compatibility" class="hash-link" aria-label="Notes on browser compatibility的直接链接" title="Notes on browser compatibility的直接链接">​</a></h2>
<p><code>Map</code> is an ES6 feature. By now most of us shouldn't be worried about its compatibility unless you are targeting a user base with some niche, old browser. By "old" I mean older than IE 11 because even IE 11 supports <a href="https://caniuse.com/mdn-javascript_builtins_map" target="_blank" rel="noopener noreferrer"><code>Map</code></a> and at this point IE 11 is <a href="https://twitter.com/swyx/status/1536353949132853248" target="_blank" rel="noopener noreferrer">dead</a>. We shouldn't be mindlessly transpiling and adding polyfills to target ES5 by default, because not only does it bloat your bundle size, it is also slower to run compared to modern JavaScript. Most importantly, it penalizes 99.999% of your users who use a modern browser.</p>
<p>Plus, we don't have to drop support for legacy browsers - serve legacy code via <code>nomodule</code> by serving fallback bundles so that we can avoid degrading the experience of visitors with modern browsers. Refer to <a href="https://www.youtube.com/watch?v=cLxNdLK--yI" target="_blank" rel="noopener noreferrer"><em>Transitioning to modern JavaScript</em></a> if you need more convincing.</p>
<p>The JavaScript language is evolving and the platform keeps getting better at optimizing modern JavaScript. We shouldn't use browser compatibility as an excuse to ignore all the improvements that have been made.</p>
<hr>
<p><em>Follow me on <a href="https://twitter.com/he_zhenghao" target="_blank" rel="noopener noreferrer">Twitter</a></em></p>]]></content>
        <author>
            <name>Zhenghao He</name>
            <uri>https://x.com/he_zhenghao</uri>
        </author>
        <category label="front end" term="front end"/>
        <category label="javascript" term="javascript"/>
        <category label="interview" term="interview"/>
        <category label="object" term="object"/>
        <category label="map" term="map"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Front End vs. Back End System Design Interviews]]></title>
        <id>https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews</id>
        <link href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews"/>
        <updated>2021-12-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Walkthrough of similarities and differences between front end vs. back end system design interviews and my thoughts on a front end career ceiling.]]></summary>
        <content type="html"><![CDATA[<p>Walkthrough of similarities and differences between front end vs. back end system design interviews and my thoughts on a front end career ceiling.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="context">Context<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews#context" class="hash-link" aria-label="Context的直接链接" title="Context的直接链接">​</a></h2>
<p>I have been interviewing a lot for the past year - not conducting interviews, I was the candidate being interviewed. Most of the interview processes I had with big tech companies consisted of 1-2 system design rounds depending on the level of the role. Unlike traditional back end-focused system design questions, for which you can find lots of prep resources online such as the famous Grokking System Design Interview or System Design Primer, I didn't know what to expect for a front end-focused system design interview as there are very few resources out there talking about this type of interviews.</p>
<p>Now that I have done a fair amount of system design interviews of both types, I want to give you a summary of what to expect, especially for the front end ones since I have been mostly working on the front end side.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="similarities">Similarities<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews#similarities" class="hash-link" aria-label="Similarities的直接链接" title="Similarities的直接链接">​</a></h2>
<p>Both front end-focused and back end-focused system design interviews share a lot of similarities in terms of the methodology you can adopt to solve the design questions:</p>
<ul>
<li>Starting with gathering system requirements</li>
<li>Laying out a clear plan and identifying major distinguishable components of the system</li>
<li>Proceeding to end-to-end API design</li>
<li>Talking about optimization</li>
</ul>
<p>Other kinds of similarities include:</p>
<ul>
<li>The interviewer is relying on you to drive the presentation. You can't rely on the interviewer to have your back.</li>
<li>While the topics can be either micro or macro, you probably won't need to actually write code - it is rare to jam some portion of coding in the middle of a system design interview</li>
<li>Unlike scantron school exams, both types will consist of mainly open ended questions. There probably isn't a checklist of things for you to cover one by one. Nor are you expected to drill deep into all of those. When you realize your interviewer is biased toward a particular part of the system, which they usually do, pivot your focus to that area. Other times you focus on your strengths and lead the conversation.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="differences">Differences<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews#differences" class="hash-link" aria-label="Differences的直接链接" title="Differences的直接链接">​</a></h2>
<p>During the back end-focused system design interviews, you would spend most of the time talking about things like:</p>
<ul>
<li>Back end/server side architecture, hand waving various back end services/components</li>
<li>Discussing which type of database to use and how to aggregate data across different shards</li>
<li>Designing SQL table schema</li>
<li>Choosing the right cross-region strategy if your service has a global user base</li>
<li>Any other kinds of system characteristics like latency, availability, fault tolerance, etc</li>
</ul>
<p>For front end-focused system design interviews, you would spend most of the time talking about stuff like:</p>
<ul>
<li>Front end/client side architecture, such as the appropriate rendering pattern to choose - client side rendering, or server side rendering or static generation or something in between?</li>
<li>What kind of data fetching mechanism to use - REST vs. GraphQL vs. gRPC and what should the APIs look like?</li>
<li>Specifics about UI components<!-- -->
<ul>
<li>A news feed which has an infinite scroll behavior with all the images lazily loaded while ensuring the client side has the aspect ratio of the images upfront to prevent layout shift.</li>
<li>An autocomplete UI component which fetches search result data incrementally in batches while receiving images from server pushes in parallel.</li>
<li>A gallery page which pulls images and displays them in the correct order despite the asynchrony that comes with the network requests that might cause them to arrive out of order.</li>
</ul>
</li>
<li>How do you leverage different layers of cache to decrease latency or support offline mode.</li>
<li>If they want to get framework-specific, which is totally possible, they might even ask you to define a particular React component's props or manage complex state in a React app.</li>
</ul>
<p>A lot of the time, having one type of system design interview means you can oversimplify the opposite side:</p>
<ul>
<li>In a back end system design interview, the client-side/front end is reduced to an API layer - you don't need to consider all the intricacies of the browser or the pesky rerenders your real-time updates would cause.</li>
<li>In a front end system design interview, you can treat the back end as a black box and you don't need to worry about how things like how to scale a database, or how your choice of using web sockets might affect the load balancers because of the need for sticky sessions support.</li>
</ul>
<p>But again, this is a summary of my experience and depending on who your interviewers are (are they front end, back end and/or fullstack developers), the scope of the role and which team it is (are you going to be on a front end team or are you expected to work across the stack and stretch into the back end?) your front end system design interview might be a bit of a hybrid where some aspects of back end system design interviews might come up.</p>
<p>Outside of the differences with the technical topics I needed to dig deep into during the interviews, I found there are two other interesting differences that stand out between the two types:</p>
<ul>
<li>For front end system design interviews I was often encouraged to treat the interviewer as the <strong>product manager</strong> and we spent some time just fleshing out the brief solution for each user story. For the back end system design interviews, we didn't really get to talk about any user interaction (I am aware that the definition of users of your system might vary, depending on whether it is customer-facing vs. developer-facing)</li>
<li>These two types of system design interviews also differ a lot in terms of estimating certain system's needs based on the potential scale of the system. The system needs can be storage needs or throughput needs or any other types of requirements.<!-- -->
<ul>
<li>It is common and expected to do these estimation during back end system design interviews since your design decision is only feasible when all of the system needs can realistically be met.</li>
<li>But for the front end system design interview, I rarely needed to do any <strong>quantitative estimation</strong> - for example, when I was designing some live feed during a front end system design interview, I didn't need to do estimations like "So let's say each message was roughly 140 characters long and it is utf8 so that's 140 bytes and an average user gets 10000 messages over a certain period of time so we ended up allocating 1.4mb memory on user devices". Again, I am not saying that this would never come up during a front end system design interview. In my experience, it is just much, much more rare compared to back end ones.</li>
</ul>
</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="career-ceiling">Career ceiling<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews#career-ceiling" class="hash-link" aria-label="Career ceiling的直接链接" title="Career ceiling的直接链接">​</a></h2>
<p>I am going to talk about something that is a little tangential. I don't think this is going to be a hot take but if you just want to pass the upcoming interviews, then you are welcome to skip this part.</p>
<p>I have done interviews for both front end focused roles and general software engineer roles. As I went through the preparation process for the system designs interviews, it just occurred to me that there is indeed a career ceiling for a pure front end focused software engineer role.</p>
<p>Ok so let's first get this out of the way - you can be extremely successful as either a front end developer or a back end developer.</p>
<p>Also it is hard to discuss any topic intelligently when we cannot agree on definitions. By saying front end developers I meant developers/engineers who solely work on the UI of a software system. And by saying career ceiling I meant the potential terminal title and the highest level such a developer/engineer can achieve in the technical individual contributor track.</p>
<p>This is an unspoken thing and a very impolite conversation. And <a href="https://twitter.com/swyx/status/1236023548227072000" target="_blank" rel="noopener noreferrer">there are exceptions</a> to this but just statistically speaking there seems to be a career ceiling for front end-only developers.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="fighting-the-inertia">Fighting the inertia<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews#fighting-the-inertia" class="hash-link" aria-label="Fighting the inertia的直接链接" title="Fighting the inertia的直接链接">​</a></h2>
<p>Part of the ceiling comes from some traditional baggage:</p>
<ul>
<li>modern front end development is fairly new compared to the back end counterpart. I have seen some bias in the industry that front end is not real engineering compared to the back end and that absolutely needs to be combated.</li>
<li>Power structures persist for a very long time and that's partially why most VPs of Eng and CTOs out there are back end/infra developers.</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="economic-reasoning">Economic reasoning<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews#economic-reasoning" class="hash-link" aria-label="Economic reasoning的直接链接" title="Economic reasoning的直接链接">​</a></h2>
<p>I had this realization when I was going through the back end system design interviews vs. the front end system design interviews — the technical topics those interviews tend to cover led me to think about some economic reasoning leading to the perception of a "Front end ceiling" as well. Your value to the company really depends on how many machines/compute/storage run through you. As a developer/engineer, that means how much money you control and front end-only developers just don't take as much. Of course front end is just as hard and as important especially for consumer facing products but at the end of the day your compute is being run on someone else's machine or device and the company just doesn't value that as much as the compute that they themselves need to pay for and to scale.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="short-lived-vs-long-running">Short-lived vs. long-running<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-vs-back-end-system-design-interviews#short-lived-vs-long-running" class="hash-link" aria-label="Short-lived vs. long-running的直接链接" title="Short-lived vs. long-running的直接链接">​</a></h2>
<p>On top of that, normally the front end/web apps are short-lived on the client side - the user opens the browser tab that loads your app and after 20 minutes they might just close the tab, and all the memory allocated by your app is on their devices from that point onward. On the other hand, the back end servers/services behind probably keep running for months or even years. One implication resulting from this difference is that you can generally get away with bad code that leads to performance problems down the road in front end apps because they are short-lived and the scale of the data they are dealing with is probably small, but you cannot ignore that in a long-running back end service.</p>
<p>Good luck with your interviews.</p>
<hr>
<p><em>Follow me on <a href="https://twitter.com/he_zhenghao" target="_blank" rel="noopener noreferrer">Twitter</a></em></p>]]></content>
        <author>
            <name>Zhenghao He</name>
            <uri>https://x.com/he_zhenghao</uri>
        </author>
        <category label="front end" term="front end"/>
        <category label="back end" term="back end"/>
        <category label="system design" term="system design"/>
        <category label="interview" term="interview"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Glimpse into Front End Interviews]]></title>
        <id>https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews</id>
        <link href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews"/>
        <updated>2021-08-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A glimpse into the front end interview process and questions that frequently come up.]]></summary>
        <content type="html"><![CDATA[
<p>A glimpse into the front end interview process and questions that frequently come up.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="interview-process">Interview Process<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#interview-process" class="hash-link" aria-label="Interview Process的直接链接" title="Interview Process的直接链接">​</a></h2>
<p>Applying for front end engineer roles is very similar to software engineer roles, but the interviews can be quite different. In my experience, for each company, there tend to be between 3 to 4 sessions. Most of them will be testing on JavaScript and discussion around web development technologies, and the rest on algorithms or behavioral.</p>
<p>One aspect that I have found interesting is that the younger the company, the more questions will lean towards JavaScript. This could be because hiring specifically for front end engineers is relatively new. Older companies used to only hire software engineers without regard to whether their focus was on the back end or front end.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="javascript-rounds">JavaScript Rounds<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#javascript-rounds" class="hash-link" aria-label="JavaScript Rounds的直接链接" title="JavaScript Rounds的直接链接">​</a></h2>
<p>JavaScript is the main focus among all the companies I have interviewed with. It makes sense as front end work nowadays is very JavaScript-heavy. HTML and CSS knowledge is no longer a necessity thanks to component libraries and the likes.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="javascript-minutiae">JavaScript Minutiae<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#javascript-minutiae" class="hash-link" aria-label="JavaScript Minutiae的直接链接" title="JavaScript Minutiae的直接链接">​</a></h3>
<p>To qualify for some companies, you might need to brush up on the minutiae of JavaScript. Topics like variable hoisting, holey arrays, non-strict mode, and switch case fall through came up. While I do not feel that knowing such things determine who is a better engineer, it is what it is. Here is my <a href="https://repl.it/@li_kai/JavaScript-Cheatsheet" target="_blank" rel="noopener noreferrer">JavaScript cheat sheet</a>.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="javascript-topics">JavaScript Topics<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#javascript-topics" class="hash-link" aria-label="JavaScript Topics的直接链接" title="JavaScript Topics的直接链接">​</a></h3>
<p>After the first assessment, live interviews tend to test on more advanced JavaScript concepts such as the event loop, promises, async/await, scope and closures.</p>
<p>If you have been writing JavaScript applications for some time and have come across a variety of situations, this should not be too hard.</p>
<p>The most frequently asked question I have ever gotten is to implement <code>debounce</code> and <code>throttle</code>:</p>
<div class="language-javascript codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-javascript codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">debounce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">fn</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> duration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter spread operator" style="color:#393A34">...</span><span class="token parameter">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// reset timeout and prevent it from triggering</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// if debounced function is called within duration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token function" style="color:#d73a49">clearTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    id </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">setTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token function" style="color:#d73a49">fn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> duration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">throttle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">fn</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> duration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter spread operator" style="color:#393A34">...</span><span class="token parameter">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// if throttled function is called within duration,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// do nothing</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">fn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    id </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">setTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      id </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// release "lock"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> duration</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// usage example</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">helloWorld</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'hello world'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> debouncedHelloWorld </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">debounce</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helloWorld</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> throttledHelloWorld </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">throttle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">helloWorld</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The second most frequently asked question is to implement a sequential <code>Promise.all</code> of sorts:</p>
<div class="language-typescript codeBlockContainer_cel3 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent__59T"><pre tabindex="0" class="prism-code language-typescript codeBlock_je4m thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QZ0V"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sequential</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fetcher</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">helper</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> results</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">length</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> results</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">fetcher</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">datum</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      results</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">datum</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">helper</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> results</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">helper</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// usage example</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">fetcher</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name builtin">Promise</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">resolve</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">setTimeout</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">resolve</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">sequential</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> fetcher</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup_d7Bp"><button type="button" aria-label="复制代码到剪贴板" title="复制" class="clean-btn"><span class="copyButtonIcons_QqjW" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_w8dp"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_DaWk"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="discussion-rounds">Discussion Rounds<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#discussion-rounds" class="hash-link" aria-label="Discussion Rounds的直接链接" title="Discussion Rounds的直接链接">​</a></h2>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="web-development-tools">Web development tools<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#web-development-tools" class="hash-link" aria-label="Web development tools的直接链接" title="Web development tools的直接链接">​</a></h3>
<p>Regardless of how we wish to deny it, web development tools are an increasingly complex and diverse ecosystem.</p>
<p>Smaller companies, especially start-ups, require engineers who have a good understanding of these tools. Larger companies will be able to abstract tooling complexity away from engineers unless the role demands it.</p>
<p>As such, web development tools like Webpack and Babel have become a common discussion topic.</p>
<p>A good understanding of tools like Webpack would be to be able to explain the following concepts:</p>
<ul>
<li>what is bundling</li>
<li>what is tree-shaking</li>
<li>what is lazy-loading and why does it matter</li>
<li>how loaders work</li>
</ul>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="react-or-web-framework-of-choice">React or web framework of choice<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#react-or-web-framework-of-choice" class="hash-link" aria-label="React or web framework of choice的直接链接" title="React or web framework of choice的直接链接">​</a></h3>
<p>If the role states that React knowledge is required, you may be expected to answer or code out React components. If you do not have React experience, using other frameworks would be possible, provided that you can explain well what is happening.</p>
<p>This may range from implementing a feature live or simply answering or explaining some React concepts such as <code>useEffect</code>'s dependencies array or <code>shouldComponentUpdate</code>.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="work-experience">Work experience<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#work-experience" class="hash-link" aria-label="Work experience的直接链接" title="Work experience的直接链接">​</a></h3>
<p>Aside from the two topics mentioned earlier, interviewers might dive into one or two things that they found interesting in your resume and ask you to elaborate.</p>
<p>As I had some experience in writing Babel plugins and jscodeshift code mods, I walked them through how I utilized those tools to help make the company codebase better.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="implementation-rounds">Implementation Rounds<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#implementation-rounds" class="hash-link" aria-label="Implementation Rounds的直接链接" title="Implementation Rounds的直接链接">​</a></h2>
<p>In all of my interviews, I have only been asked to implement a feature twice. It is not a common question, but it may come up.</p>
<p>This would come down to how well-versed you are with your basics such as HTML and CSS, as well as tools and frameworks. As an example, one of the questions I have gotten was to implement an autocomplete search bar like Google's. If you have built something like that before, it is doable within an hour.</p>
<p>Implementation rounds feel very similar to algorithms, as you need to actively find the best solution while thinking out loud and explaining your decisions.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="algorithm-rounds">Algorithm Rounds<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#algorithm-rounds" class="hash-link" aria-label="Algorithm Rounds的直接链接" title="Algorithm Rounds的直接链接">​</a></h2>
<p>As software engineers, we are not unfamiliar with algorithm questions. Leetcode and Hackerrank are common resources used for practicing such questions.</p>
<p>As I knew this was my weakness, this was where I spent the most time. It may be a little ironic that I chose Python over JavaScript as my language of choice for tackling algorithms. JavaScript's lack of a native minheap and binary search implementation made it a slightly worse choice.</p>
<p>For those who are just starting to learn Python or getting back into it, here's my <a href="https://repl.it/@li_kai/Python-Cheatsheet" target="_blank" rel="noopener noreferrer">Python cheat sheet</a>.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="conclusion">Conclusion<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/a-glimpse-into-front-end-interviews#conclusion" class="hash-link" aria-label="Conclusion的直接链接" title="Conclusion的直接链接">​</a></h2>
<p>Front end software engineer roles are not very different from general software engineer roles, but they do tend to be more specialized and in some ways, require even more effort.</p>
<p>If you are passionate about this field and interested in what you do, this would not be too high of a hurdle. I hope my experience and tips were useful to you, and good luck in your search!</p>]]></content>
        <author>
            <name>Kai Li</name>
            <uri>https://github.com/li-kai</uri>
        </author>
        <category label="front end" term="front end"/>
        <category label="interview" term="interview"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Front End Career Questions]]></title>
        <id>https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-career-questions</id>
        <link href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-career-questions"/>
        <updated>2021-08-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Recently a junior front end engineer at a startup in Singapore reached out to me to ask me about front end development as a career.]]></summary>
        <content type="html"><![CDATA[
<p>Recently a junior front end engineer at a startup in Singapore reached out to me to ask me about front end development as a career.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="my-manager-told-me-that-currently-its-a-bit-hard-to-define-requirements--expectations-for-higher-tier--higher-individual-contributor-ic-level-for-front-end-engineers-in-the-organization-since-you-are-working-at-facebook-i-am-wondering-what-are-some-requirements--expectations-for-higher-ic-level-there-for-front-end-engineers-maybe-around-ic4-ic5-and-above-if-thats-kinda-the-level-you-use-there">My manager told me that currently it's a bit hard to define requirements &amp; expectations for higher tier / higher Individual Contributor (IC) level for Front End engineers in the organization. Since you are working at Facebook, I am wondering what are some requirements &amp; expectations for higher IC level there for Front End engineers (maybe around IC4, IC5 and above if that's kinda the level you use there)?<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-career-questions#my-manager-told-me-that-currently-its-a-bit-hard-to-define-requirements--expectations-for-higher-tier--higher-individual-contributor-ic-level-for-front-end-engineers-in-the-organization-since-you-are-working-at-facebook-i-am-wondering-what-are-some-requirements--expectations-for-higher-ic-level-there-for-front-end-engineers-maybe-around-ic4-ic5-and-above-if-thats-kinda-the-level-you-use-there" class="hash-link" aria-label="My manager told me that currently it's a bit hard to define requirements &amp; expectations for higher tier / higher Individual Contributor (IC) level for Front End engineers in the organization. Since you are working at Facebook, I am wondering what are some requirements &amp; expectations for higher IC level there for Front End engineers (maybe around IC4, IC5 and above if that's kinda the level you use there)?的直接链接" title="My manager told me that currently it's a bit hard to define requirements &amp; expectations for higher tier / higher Individual Contributor (IC) level for Front End engineers in the organization. Since you are working at Facebook, I am wondering what are some requirements &amp; expectations for higher IC level there for Front End engineers (maybe around IC4, IC5 and above if that's kinda the level you use there)?的直接链接">​</a></h3>
<p>For smaller companies that might be true, but it's still possible if you don't limit yourself to front end work. Going up the levels is all about scope and complexity. IC3s (Junior Engineer) work on tasks, IC4s (Software Engineer) work on features, IC5s (Senior Software Engineer) work on projects, IC6s (Staff Software Engineer) work on huge projects spanning across teams, IC7s (Senior Staff Software Engineer) work on projects spanning across the org, IC8+s (Principal Software Engineer) work on projects spanning across the company or even influencing the industry. If you're able to show that you can handle scope of that magnitude, there shouldn't be a reason not to be compensated at that level. That said, the rough guide I proposed here is for a company the size of Facebook where we have 10s of thousands of Engineers. Doing work that impacts an entire company of 10 people likely won't be IC8 level work. For reference, React core team is mostly made up of IC5s/IC6s and one IC7. Flow has a number of IC5s and IC6s as it's technically complex and affects how the entire company writes JavaScript. GraphQL has many senior engineers and the creator of GraphQL is currently a director (IC8 equivalent).</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="are-you-still-doing-a-lot-of-front-end-related-development-work-now-be-it-in-the-company-or-personally-if-yes-i-am-just-curious-what-are-the-things-you-often-do-and-what-do-you-like-in-particular-about-front-end-development">Are you still doing a lot of Front End-related development work now? Be it in the company or personally? If yes, I am just curious what are the things you often do, and what do you like in particular about Front End development?<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-career-questions#are-you-still-doing-a-lot-of-front-end-related-development-work-now-be-it-in-the-company-or-personally-if-yes-i-am-just-curious-what-are-the-things-you-often-do-and-what-do-you-like-in-particular-about-front-end-development" class="hash-link" aria-label="Are you still doing a lot of Front End-related development work now? Be it in the company or personally? If yes, I am just curious what are the things you often do, and what do you like in particular about Front End development?的直接链接" title="Are you still doing a lot of Front End-related development work now? Be it in the company or personally? If yes, I am just curious what are the things you often do, and what do you like in particular about Front End development?的直接链接">​</a></h3>
<p>I'm still doing a lot of Front End development for work. Less in a personal capacity ever since I stopped working on Docusaurus as a side project. You can check out my GitHub to see what stuff I've done. At work I'm in-charge of oculus.com and built the infra for it. I built a design system of React components for the content developers to develop the marketing pages.</p>
<p>I really like all aspects of Front End development, maybe except optimizing performance. At FB we build a lot of Front End-related tooling (e.g. Jest, GraphQL, Flow) and libraries (our internal CSS-in-JS solution, Docusaurus, React, Flux, etc) which is personally very exciting to me. Even within front end development, there are various layers - very user-facing stuff (HTML/CSS/visual related code) and back end (JavaScript stuff, network layer, storage), tooling (ESLint, Babel, TypeScript, webpack). I call myself a full front end stack developer as I'm decent across the entire front end stack. I'm especially excited about tooling work as the problems there are interesting and challenging. Typically only large companies face such problems because they only occur at scale, hence I really like being at FB because FB is one of such companies.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="personally-do-you-have-any-tips-on-how-best-to-grow-as-a-front-end-engineer-are-there-any-particular-areas-that-youd-recommend">Personally, do you have any tips on how best to grow as a Front End engineer? Are there any particular areas that you'd recommend?<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-career-questions#personally-do-you-have-any-tips-on-how-best-to-grow-as-a-front-end-engineer-are-there-any-particular-areas-that-youd-recommend" class="hash-link" aria-label="Personally, do you have any tips on how best to grow as a Front End engineer? Are there any particular areas that you'd recommend?的直接链接" title="Personally, do you have any tips on how best to grow as a Front End engineer? Are there any particular areas that you'd recommend?的直接链接">​</a></h3>
<p>Learn your fundamentals well. There are many UI and CSS libraries out there, but a good Front End developer still needs to know how to build a website without them. Peek beneath the abstraction layers and understand the problems these libraries are trying to solve, do not use them blindly. Keep building stuff - try to build a simple version of the libraries you frequently use, build interesting user interfaces and products, etc.</p>
<h3 class="anchor anchorWithStickyNavbar_LSVY" id="what-do-you-think-about-developing-breadth-wise-vs-depth-wise-for-example-do-you-think-its-important-for-a-software-engineer-to-know-more-about-other-fields-besides-the-one-they-are-currently-working-on-in-particular-what-do-you-think-about-a-front-end-engineer-who-knows-be-ie-a-full-stack-developer-or-a-front-end-engineer-who-knows-mobile-development-with-the-advent-of-react-native-or-flutter">What do you think about developing breadth-wise vs depth-wise? For example, do you think it's important for a software engineer to know more about other fields besides the one they are currently working on? In particular, what do you think about a Front End engineer who knows BE (i.e. a full-stack developer), or a Front End engineer who knows mobile development (with the advent of React Native or Flutter)?<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/front-end-career-questions#what-do-you-think-about-developing-breadth-wise-vs-depth-wise-for-example-do-you-think-its-important-for-a-software-engineer-to-know-more-about-other-fields-besides-the-one-they-are-currently-working-on-in-particular-what-do-you-think-about-a-front-end-engineer-who-knows-be-ie-a-full-stack-developer-or-a-front-end-engineer-who-knows-mobile-development-with-the-advent-of-react-native-or-flutter" class="hash-link" aria-label="What do you think about developing breadth-wise vs depth-wise? For example, do you think it's important for a software engineer to know more about other fields besides the one they are currently working on? In particular, what do you think about a Front End engineer who knows BE (i.e. a full-stack developer), or a Front End engineer who knows mobile development (with the advent of React Native or Flutter)?的直接链接" title="What do you think about developing breadth-wise vs depth-wise? For example, do you think it's important for a software engineer to know more about other fields besides the one they are currently working on? In particular, what do you think about a Front End engineer who knows BE (i.e. a full-stack developer), or a Front End engineer who knows mobile development (with the advent of React Native or Flutter)?的直接链接">​</a></h3>
<p>I somewhat answered this in another <a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/are-front-end-development-skills-enough-for-a-career">blog post</a>. Lemme know if your question isn't answered after reading it.</p>]]></content>
        <author>
            <name>Yangshun Tay</name>
            <uri>https://github.com/yangshun</uri>
        </author>
        <category label="front end" term="front end"/>
        <category label="career" term="career"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Are Front End Development Skills Enough for a Career?]]></title>
        <id>https://www.frontendinterviewhandbook.com/zh-CN/blog/are-front-end-development-skills-enough-for-a-career</id>
        <link href="https://www.frontendinterviewhandbook.com/zh-CN/blog/are-front-end-development-skills-enough-for-a-career"/>
        <updated>2019-11-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Recently, an undergrad freshmen I met at an event asked me a question regarding Front End development as a career.]]></summary>
        <content type="html"><![CDATA[
<p>Recently, an undergrad freshmen I met at an event asked me a question regarding Front End development as a career.</p>
<blockquote>
<p>I'm honestly quite into front end development — web technologies, UI/UX, web design and stuff. But with there being more and more accessible to new developers (create-react-app, parcel and such), I just can't help but wonder if these skills are sufficient to survive in the tech industry today. Not that it's a bad thing! Lowering the barrier to entry for programmers is always good. However, for those like myself who would like to pursue front end development as a career, I'm just wondering if having these skills are enough.</p>
</blockquote>
<p>Interesting question. I've asked myself the same question before but convinced myself that I'm probably fine just dabbling in Front End development for now. 😌</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="front-end-is-complex-and-getting-increasingly-so">Front End is complex and getting increasingly so<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/are-front-end-development-skills-enough-for-a-career#front-end-is-complex-and-getting-increasingly-so" class="hash-link" aria-label="Front End is complex and getting increasingly so的直接链接" title="Front End is complex and getting increasingly so的直接链接">​</a></h2>
<p>Most people would have used websites like facebook.com, youtube.com and gmail.com. These applications have hundreds of engineers working on them (thousands if you include the back end) due to the demanding nature of the application - it has to load fast, it has to be secure, it has to look pretty. These days, front end development is no longer just about building websites rendering static HTML. Many websites these days are in fact web applications and a lot of thought has to be put into the application architecture, and that requires good software engineering capabilities.</p>
<p>That's why you see many Front End tools these days like React, Redux, Relay, CSS modules, webpack, etc. These tools exist because of the ever-increasing requirements of building rich and performant user experiences on the web. Being a good Front End developer is very hard, there are many aspects to know about - HTML, CSS, JavaScript, Browser APIs, Security, Performance, Animation, SEO, Networking, the list is non-exhaustive and growing. There are always new problems to solve and new things to learn. <a href="https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4" target="_blank" rel="noopener noreferrer">JavaScript fatigue</a> was a term pretty common a few years back due to the explosion of tools in the Front End ecosystem. Things have gotten more stable but the JavaScript community is currently still one of the fastest-moving communities.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="does-the-rise-of-mobile-threaten-the-existence-of-web-developers">Does the rise of mobile threaten the existence of web developers?<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/are-front-end-development-skills-enough-for-a-career#does-the-rise-of-mobile-threaten-the-existence-of-web-developers" class="hash-link" aria-label="Does the rise of mobile threaten the existence of web developers?的直接链接" title="Does the rise of mobile threaten the existence of web developers?的直接链接">​</a></h2>
<p>Many products now have a native mobile app version and that might make people think that the existence of Front End (web) developers could be threatened. I think that is only true to a small extent. Certain applications like Uber and Lyft make sense to be mobile-first, but there are also many complex professional applications where web (or any interface with a larger screen) will always prevail, such as office productivity and design software. Viewing things at a more macro scale, both mobile apps and web apps fall under the category of client-side applications. Many core skills important for being a good web developer are also important for mobile app development - they are transferable across platforms.</p>
<p>Tools like <a href="https://reactnative.dev/" target="_blank" rel="noopener noreferrer">React Native</a> and <a href="https://flutter.dev/" target="_blank" rel="noopener noreferrer">Flutter</a> have also been created to help engineers build products across platforms by only writing the code "once" (in quotes because that dream is still in development). This approach is not a silver bullet solution and has yet to prove itself adequately, but for prototyping small apps or even just certain parts of your mobile app, it works pretty well. In React Native, you write your application in JavaScript using React Native primitives, and the React Native runtime runs the code on the JavaScript engine in the platform to construct native app UI views and handle application logic. It's pretty similar to writing typical web front end code. Facebook's Ads Manager App and the Marketplace tab are built using React Native. There are numerous technologies that enable you to build native apps on mobile platforms by knowing web front end development.</p>
<p>Even though mobile usage is on the rise, there still exist many use cases at which the desktop excels. Google Suite, Microsoft Office, Design tools are still more efficiently operated on desktops. In fact, many desktop applications these days are built on HTML5 technologies instead of native desktop code using tools like Electron to package web application code into an executable shipped to users. You might already be using some of them without knowing - Slack, Discord, WhatsApp Desktop, VS Code, Atom Editor, just to name a few. I think developers who are only familiar with native desktop platform engineering skills have more reasons to worry than Front End developers.</p>
<p>The web is incredibly cross-platform!</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="jack-of-all-trades-master-of-one">Jack of all trades, master of one<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/are-front-end-development-skills-enough-for-a-career#jack-of-all-trades-master-of-one" class="hash-link" aria-label="Jack of all trades, master of one的直接链接" title="Jack of all trades, master of one的直接链接">​</a></h2>
<p>However, I think that being a Front End developer in many regards, is considered a specialized position. That's why it's important to be "T-shaped". I first got introduced to this term through my ex-manager at Grab, Tim Goh. He advised me to have a specialization (front end), yet still know a bit about everything. In other words, you are strong in your core fundamentals, but you also specialize in a particular area.</p>
<p>This is good advice and it's not new advice. In most university courses, students are expected to study the fundamental courses before choosing their area of specialization. In the context of a School of Computing in National University of Singapore, students start out in school by taking basic classes in Algorithms, Data Structures, Software Engineering, Operating Systems, Computer Networks, before choosing their specialization in deeper areas like Compilers, Computer Graphics, AI and Machine Learning, Media, Networking and more.</p>
<p>Having a strong foundation enables someone to make switching domains a possibility. There will definitely be a ramp-up process, but it can be made smoother with solid foundations, and with the skill of learning how to learn fast. In the extreme case where the web becomes irrelevant, and no companies want to hire front end developers anymore, front end developers with strong fundamentals can always slightly switch tracks by doing mobile or back end engineering, or even the hottest UI platform (AR/VR?) out there.</p>
<p>Having good tools to use (like Create React App, Parcel) doesn't eradicate the need for Front End developers to possess good software engineering skills. What will happen if you are the person tasked to build the tools? Good Front End developers (or Software Engineers really) go beneath the abstraction layer, understand how their tools work, and what problems the tool set out to solve. They also constantly seek to challenge and improve the status quo by building better technologies to cater to the ever-increasing demands.</p>
<p>At Facebook, the Front End Engineers are Software Engineers first, domain experts second. Many of the Front End engineers I know at Facebook have a deep understanding of the technical stack and don't just work on stuff related to the browser. At Facebook scale, front end work also involves building a lot of infrastructure to make our front end code base scale well with the growing technical and people needs. That means writing <a href="https://github.com/facebook/jscodeshift" target="_blank" rel="noopener noreferrer">codemods</a> to do large-scale refactoring, inventing new <a href="https://react.dev/" target="_blank" rel="noopener noreferrer">UI</a> <a href="https://facebookarchive.github.io/flux/" target="_blank" rel="noopener noreferrer">paradigms</a>, performant <a href="https://jestjs.io/" target="_blank" rel="noopener noreferrer">testing frameworks</a>, creating <a href="https://flow.org/" target="_blank" rel="noopener noreferrer">type-checkers</a> for untyped languages, changing the ways we <a href="https://graphql.org/" target="_blank" rel="noopener noreferrer">fetch data</a> from our servers and <a href="https://relay.dev/" target="_blank" rel="noopener noreferrer">managing it on clients</a>. These tools wouldn't exist if the Front End engineers at Facebook didn't possess strong software engineering skills.</p>
<h2 class="anchor anchorWithStickyNavbar_LSVY" id="pick-up-new-relevant-skills">Pick up new, relevant skills<a href="https://www.frontendinterviewhandbook.com/zh-CN/blog/are-front-end-development-skills-enough-for-a-career#pick-up-new-relevant-skills" class="hash-link" aria-label="Pick up new, relevant skills的直接链接" title="Pick up new, relevant skills的直接链接">​</a></h2>
<p>It can be hard to pick up new skills at work in an unrelated domain if there are no opportunities to do so. Thankfully (or not), due to the explosion of tools in the Front End ecosystem, I've found an area which I have gained a new-found interest in - Programming Languages Theory (Static Analysis, Compilers, and Interpreters). Static analysis is incredibly important in tools that I use on a daily basis - it's being used by the module bundlers for bundling JavaScript files together, generating CSS from more user-friendly CSS syntaxes, compiling modern JavaScript into older versions of JavaScript that more common browsers can run, and even this blog post written in Markdown uses static analysis to be converted into HTML.</p>
<p>I've been toying with writing my own interpreter after learning this awesome book called <a href="http://www.craftinginterpreters.com/" target="_blank" rel="noopener noreferrer">Crafting Interpreters</a> and will be further exploring this domain in my spare time, possibly building Front End-related tooling in future that leverages static analysis and compilation.</p>
<p>Adding new skills to my arsenal in a related but different domain helps me to stay relevant in the event that the industry no longer needs Front End developers 😱</p>
<hr>
<p>In summary, although Front End development is considered quite specialized, there's enough demand and complexity for it to stay relevant in the years to come. What would threaten the web would be an entire shift of the way users interact with apps, perhaps to a non-visual paradigm like a brain-controlled interface. However, paradigm shifts don't happen overnight and there will be sufficient time to react (pun intended) in the case that ever happens. Being strong in your Software Engineering fundamentals and knowing how to learn new skills fast will help you in switching domains (and also careers).</p>
<p><em>Opinions are my own and do not represent the views of my employer.</em></p>]]></content>
        <author>
            <name>Yangshun Tay</name>
            <uri>https://github.com/yangshun</uri>
        </author>
        <category label="front end" term="front end"/>
        <category label="career" term="career"/>
    </entry>
</feed>