{
    "componentChunkName": "component---src-templates-blog-post-tsx",
    "path": "/blog/2018-09-18-four-reasons-to-use-append-instead-of-object-assign-and-object-spread/",
    "result": {"data":{"blogPost":{"title":"Four reasons to use append() instead of Object.assign() and Object spread","slug":"/blog/2018-09-18-four-reasons-to-use-append-instead-of-object-assign-and-object-spread/","authorNodes":[{"name":"Charles Lowell","slug":"/people/charles-lowell/"}],"markdown":{"html":"<blockquote>\n<p>Warning! This post was manufactured in a facility that also processes Monoids and may contain traces of functional programming.</p>\n</blockquote>\n<p>I'd like to share with you what is easily one of my top 5 favorite discoveries in programing during the last year: The <code class=\"language-text\">append</code> operation for JavaScript Objects. Before you go looking in the API docs: no, this is not part of the official ECMA Script specification. It's a pattern that I found on the internet and implemented in <a href=\"https://github.com/cowboyd/funcadelic.js\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">funcadelic.js</a>. You can use my implementation, or you can write your own, but either way, once you experience how much better <code class=\"language-text\">append</code> tastes than its analogues in vanilla JavaScript, you'll have a really hard time going back.</p>\n<p>The TL;DR is that you can use <code class=\"language-text\">append</code> anywhere that you would use <code class=\"language-text\">Object.assign</code> or the <a href=\"https://redux.js.org/recipes/usingobjectspreadoperator\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">object spread operator</a> except it's more awesome. How? Well I'm glad you asked.</p>\n<h3 id=\"append-is-immutable\" style=\"position:relative;\"><a href=\"#append-is-immutable\" aria-label=\"append is immutable permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code class=\"language-text\">append</code> is immutable.</h3>\n<p>It never changes any of its arguments, only ever creates new objects that are derived from the objects that you give it.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">let</span> ingredients <span class=\"token operator\">=</span> <span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">eggs</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">mushrooms</span><span class=\"token operator\">:</span> <span class=\"token number\">10</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token comment\">//=> { eggs: 2, mushrooms: 10 }</span></code></pre></div>\n<p>I'll not try to convince you of the benefits of immutability here, only say that as programmers, we truck in that most precious of resources: <em>information</em>. Why willingly destroy it unless absolutely necessary?</p>\n<p>When you use <code class=\"language-text\">append</code> instead of <code class=\"language-text\">Object.assign</code>, you'll never have to pay the overhead of that decision, or worse, accidentally mutate some object you never intended to.</p>\n<h3 id=\"append-preserves-type\" style=\"position:relative;\"><a href=\"#append-preserves-type\" aria-label=\"append preserves type permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code class=\"language-text\">append</code> preserves type.</h3>\n<p>Every JavaScript object has a runtime type. This lets us define custom properties and operations on it. Unfortunately, if we're making an immutable transformation using <code class=\"language-text\">Object.assign</code> or Object spread, that type information is erased and no matter what we started out with we revert to a plain old JavaScript object.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Person</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">firstName<span class=\"token punctuation\">,</span> lastName</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>firstName <span class=\"token operator\">=</span> firstName<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>lastName <span class=\"token operator\">=</span> lastName<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">get</span> <span class=\"token function\">fullName</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>firstName<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\"> </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>lastName<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">let</span> misspelled <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Person</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Tony\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Stork\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">let</span> corrected <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token operator\">...</span>misspelled<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">lastName</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Stark\"</span> <span class=\"token punctuation\">}</span> <span class=\"token punctuation\">}</span>\n<span class=\"token comment\">//=> Object { firstName: \"Tony\", lastName: \"Stark\" }</span>\n\ncorrected<span class=\"token punctuation\">.</span>fullName\n<span class=\"token comment\">//=> undefined</span></code></pre></div>\n<p>Notice how the fact that we're work working with a <code class=\"language-text\">Person</code> object is just thrown into the dumpster? By contrast, <code class=\"language-text\">append</code> always preserves type of object that we were working with before.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">let</span> misspelled <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Person</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Tony\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Stork\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">let</span> corrected <span class=\"token operator\">=</span> <span class=\"token function\">append</span><span class=\"token punctuation\">(</span>misspelled<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">lastName</span><span class=\"token operator\">:</span> <span class=\"token string\">\"Stark\"</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">//=> Person { firstName: \"Tony\", lastName: \"Stark\" }</span>\ncorrected<span class=\"token punctuation\">.</span>fullName <span class=\"token comment\">//=> \"Tony Stark\"</span></code></pre></div>\n<p>I mean you <em>could</em> throw away the type by default, but why?</p>\n<h3 id=\"append-is-lazy\" style=\"position:relative;\"><a href=\"#append-is-lazy\" aria-label=\"append is lazy permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code class=\"language-text\">append</code> is lazy</h3>\n<p>JavaScript has a really nice feature called <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">getters</a> or \"computed properties\" that lets you defer evaluating a property's value until it's actually needed. This can be a great way to avoid computing a property if the dependencies required won't be available until later, or you'd just rather not pay the cost of evaluation until you absolutely need to.</p>\n<p>Unfortunately, whatever your reasons, both <code class=\"language-text\">Object.assign</code> and Object spread will interfere with them because they eagerly evaluate each property of the objects being copied over into the result. For example, let's look at these two objects that have computed properties:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">let</span> left <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">get</span> <span class=\"token function\">thousand</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'calculating 1000 in a really expensive way'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">let</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">1000</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> i<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">let</span> right <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">get</span> <span class=\"token function\">hundred</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'calculating 100 in a really expensive way'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">let</span> i <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">for</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">;</span> i <span class=\"token operator\">&lt;</span> <span class=\"token number\">100</span><span class=\"token punctuation\">;</span> i<span class=\"token operator\">++</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> i<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Let's see what happens when we combine them with Object spread:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">let</span> both <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token operator\">...</span>left<span class=\"token punctuation\">,</span> <span class=\"token operator\">...</span>right<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// [LOG] calculating 1000 in a really expensive way</span>\n<span class=\"token comment\">// [LOG] calculating 100 in a really expensive way</span></code></pre></div>\n<p>Or how about <code class=\"language-text\">Object.assign</code>?</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">let</span> both <span class=\"token operator\">=</span> Object<span class=\"token punctuation\">.</span><span class=\"token function\">assign</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// [LOG] calculating 1000 in a really expensive way</span>\n<span class=\"token comment\">// [LOG] calculating 100 in a really expensive way</span></code></pre></div>\n<p>But we made those properties lazy for a reason! Just because I'm deriving a new object based off of those properties, doesn't mean I should have to evaluate them! Well with <code class=\"language-text\">append</code> you don't. It will follow the guidelines laid down by each object's original creator and keep normal properties normal, and computed properties computed.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">let</span> both <span class=\"token operator\">=</span> <span class=\"token function\">append</span><span class=\"token punctuation\">(</span>left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// nothing printed, because nothing evaluated!</span>\n<span class=\"token comment\">// only when we access the properties does the computation run.</span>\n\nboth<span class=\"token punctuation\">.</span>thousand <span class=\"token comment\">//=> 1000</span>\n<span class=\"token comment\">// [LOG] calculating 1000 in a really expensive way</span>\n\nboth<span class=\"token punctuation\">.</span>hundred <span class=\"token comment\">//=> 100</span>\n<span class=\"token comment\">// [LOG] calculatingc 100 in a really expensive way</span></code></pre></div>\n<h3 id=\"append-is-a-universal-interface\" style=\"position:relative;\"><a href=\"#append-is-a-universal-interface\" aria-label=\"append is a universal interface permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code class=\"language-text\">append</code> is a universal interface.</h3>\n<p>Remember when I said that I found <code class=\"language-text\">append</code> on the internet? That was true, but it also wasn't the full story. What I <em>actually</em> found on the internet was something far more powerful: the concept of a <em>semigroup</em>. A semigroup is (roughly) a type; any two of whose values can be combined with each other to produce a new value of the same type. For example, JavaScript <code class=\"language-text\">Array</code> is a semigroup. I can combine or \"append\" any two <code class=\"language-text\">Array</code> objects together to produce a single new <code class=\"language-text\">Array</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">[</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">]</span> <span class=\"token comment\">//=> [1, 2, 3, 4]</span></code></pre></div>\n<p>JavaScript <code class=\"language-text\">String</code> is a semigroup too!</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token string\">'Hello'</span> <span class=\"token operator\">+</span> <span class=\"token string\">' World!'</span> <span class=\"token comment\">//=> Hello World</span></code></pre></div>\n<p>This got me to thinking: what would a semigroup for object look like? What would it mean to take two <code class=\"language-text\">Object</code>s and combine them to produce another <code class=\"language-text\">Object</code>, and the <code class=\"language-text\">append()</code> function that I've been talking about was the inevitable consequence:</p>\n<ol>\n<li><em>Immutable</em> because this is functional programming, and that's really just a given.</li>\n<li><em>Type-preserving</em>: because the append operation of Semigroup must return the same type as its arguments.</li>\n<li><em>Lazy</em>: This isn't <em>strictly</em> a requriment, but as long as we're building an amped up version of <code class=\"language-text\">Object.assign</code> we might as well respect object property semantics, no?</li>\n</ol>\n<p>This is all to say that using <code class=\"language-text\">append</code> <em>normalizes</em> this operation to a shared understanding of what a Semigroup is. And in fact, in funcadelic.js, the <code class=\"language-text\">append</code> operation will work on all these types.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">//=> [1, 2, 3, 4]</span>\n<span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Hello'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">' World!'</span><span class=\"token punctuation\">)</span> <span class=\"token comment\">//=> 'Hello World!'</span>\n<span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">eggs</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">bacon</span><span class=\"token operator\">:</span> <span class=\"token number\">2</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">//=> { eggs: 2, bacon: 2 }</span></code></pre></div>\n<p>One concept, one function, lots and lots of different scenarios. And that's why I started using <code class=\"language-text\">append</code> and haven't looked back since.</p>","frontmatter":{"date":"September 18, 2018","description":"Object.assign is just a special case of a universal concept in functional programming. By opting to use a universal function to back this universal concept, you can inherit all kinds of awesome for free.","tags":["javascript","functional-programming"],"img":{"childImageSharp":{"fixed":{"src":"/static/ffe8863c073fd4b2e4ba00507530a5db/31987/2018-09-18-four-reasons-to-use-append-instead-of-object-assign-and-object-spread_merge-sign.png"}}}}}}},"pageContext":{"id":"84f0ec8c-88e1-5a23-9815-7a2fff97e52b"}},
    "staticQueryHashes": ["1241260443"]}