title: ES6 React - What are the difference between reference, shallow copy and deep copy and how to compare them?
body: <p>I know this question has been discussed so many times, and I think I got a basic idea. There are some top rated answers I found from StackOverflow:  </p>
  
  <ul>
  <li><a href="https://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy">What is the difference between a deep copy and a shallow copy?</a>  </li>
  <li><a href="https://stackoverflow.com/questions/9912794/deep-copy-and-shallow-copy">Deep Copy and Shallow Copy</a> </li>
  </ul>
  
  <p>But all the answers seems very fuzzy to me.<br>
  Let's consider the example below:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="true">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const user = {
    name: "James",
    age: 33,
    highlights: {
      career: "Basketball player",
      NBAChampion: [2012, 2013, 2016],
    },
    promotion: () =&gt; ("Get LeBron15 now!"),
  };
  
  const james = user;
  const clone = { ...user };
  const clone2 = Object.assign({}, user);
  const clone3 = JSON.parse(JSON.stringify(user));
  const clone4 = {
    ...user,
    highlights: {
      ...user.highlights,
      // I comment the it out, so now NBAChampion is a reference rather than copy!
      // NBAChampion: [...user.highlights.NBAChampion]
    }
  };
  
  user.age++;
  user.highlights.career = "football player";
  
  console.log('james', james, james === user, james == user);
  console.log('clone', clone, clone === user, clone == user);
  console.log('clone2', clone2, clone2 === user, clone2 == user);
  console.log('clone3', clone3, clone3 === user, clone3 == user);
  // console.log(clone3.promotion()); // My problem with clone3 is that function's been removed. 
  console.log('clone4', clone4, clone4 === user, clone4 == user);</code></pre>
  </div>
  </div>
  </p>
  
  <ul>
  <li><code>james</code> is a reference, it's always exactly same as user;</li>
  <li><code>clone</code> is a copy. <strong>Is it a shallow copy or deep copy?</strong> The <code>name</code> and <code>age</code> are separated from <code>user</code>, but the <code>highlights</code> is still a reference.</li>
  <li><code>clone2</code> behaves exactly the same as <code>clone</code>.</li>
  <li><code>clone3</code> is converted from a string. <strong>Is it a deep copy?</strong> It is not a perfect clone, since functions (<em>if there's any</em>) are not save to convert this way.</li>
  <li><code>clone4</code> is copied every layer of <code>user</code>, so I can call it a "deep copy".<br>
  However if the <em>spread operator</em> only creates deep copy <strong>sometimes</strong>, then <strong>how can I test if the new object is a deep copy or not?</strong></li>
  </ul>
  
  <p><strong>Update</strong>: I commented <code>NBAChampion</code> out in <code>clone4</code>, so now NBAChampion is a reference rather than copy! If I push a new value in <code>user.highlights.NBAChampion</code>, <code>clone4</code> will also updates.<br>
  <strong>What should we call this type of object?</strong> It's neither a shallow nor deep copy. </p>
  
  <hr>
  
  <h2>Why does this matter?</h2>
  
  <p><strong>React</strong> has a <code>shouldComponentUpdate()</code> function which compares shallow copy. There is the <a href="https://reactjs.org/docs/react-component.html#shouldcomponentupdate" rel="noreferrer">link</a>.<br>
  In React <a href="https://github.com/facebook/react/blob/8e5f12ca6c18fb48ea71cba6bfa9bd7cf499ccb6/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.internal.js" rel="noreferrer">source code (Line: 356)</a>, the <strong>shallow comparison</strong> is done like this:</p>
  
  <pre><code>shouldComponentUpdate(nextProps) {
    return this.props.children !== nextProps.children;
  }
  </code></pre>
  
  <p>In the code demo above, the 2nd and 3rd parameters in <code>console.log</code> show the comparison results between <code>clone</code> and <code>user</code>. However, only 1st copy returns <code>true</code>. (<em>Note: there is no different between strict comparison and abstract comparison</em>)</p>
  
  <p>If I apply <code>shouldComponentUpdate</code> to the demo above, obviously only <code>james</code> and <code>user</code> will return <code>true</code>. So <code>james</code> is a shallow copy in Facebook's code. Then my questions are:    </p>
  
  <ul>
  <li><em>Are reference and shallow copy exactly the same thing in JS? If not, why React do this?</em></li>
  <li><em>How can I test a object is a shallow copy or deep copy in my test case?</em></li>
  </ul>
  
  <p>The question took me lots of time to craft. Any clear explanation with example is welcome.<br>
  Thanks a lot.</p>