Javascript Object References

When dealing with Javascript object references, it’s essential to comprehend how variable assignments and function calls interact with objects in memory.

Consider a scenario where you want to use map on an array but also need to pass an additional parameter to the callback. One approach to accomplish this is using bind:

<span class="token keyword">function</span> <span class="token function">mapper</span><span class="token punctuation">(</span><span class="token parameter">extra<span class="token punctuation">,</span> entity</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// do stuff with extra</span>
  <span class="token keyword">return</span> entity<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">const</span> result <span class="token operator">=</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 number">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token function">mapper</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> extra<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

In this code, bind allows the mapper function to receive an extra parameter. However, an issue arises if you expect the original array to be modified directly, as map returns a new array.

For instance, the following code works because the object properties are modified in place:

<span class="token keyword">let</span> rows <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'A'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'B'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'C'</span> <span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
rows<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> obj<span class="token punctuation">.</span>desc <span class="token operator">=</span> <span class="token string">'something'</span><span class="token punctuation">;</span> <span class="token keyword">return</span> obj<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// [ { id: 1, title: 'A', desc: 'something' }, ... ]</span>
console<span class="token punctuation">.</span><span class="token function">dir</span><span class="token punctuation">(</span>rows<span class="token punctuation">)</span><span class="token punctuation">;</span>

However, this code does not produce the same effect:

<span class="token keyword">let</span> rows <span class="token operator">=</span> <span class="token punctuation">[</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'A'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'B'</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'C'</span> <span class="token punctuation">}</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
rows<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">id</span><span class="token operator">:</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'D'</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">return</span> obj<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// [ { id: 1, title: 'A' }, ... ]</span>
console<span class="token punctuation">.</span><span class="token function">dir</span><span class="token punctuation">(</span>rows<span class="token punctuation">)</span><span class="token punctuation">;</span>

To explain, in Javascript, passing a variable to a function essentially passes a reference to the data in memory. When modifying properties of an object inside a callback, the changes reflect on the original objects in the array because they point to the same memory location.

For example:

<span class="token keyword">const</span> f0 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">f</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> f1 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">f</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> f2 <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">f</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 keyword">const</span> arr0 <span class="token operator">=</span> <span class="token punctuation">[</span>f0<span class="token punctuation">,</span> f1<span class="token punctuation">,</span> f2<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> arr1 <span class="token operator">=</span> arr0<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">ent</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
  ent <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">f</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> ent<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// [ { f: 0 }, { f: 1 }, { f: 2 } ]</span>
console<span class="token punctuation">.</span><span class="token function">dir</span><span class="token punctuation">(</span>arr0<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// [ { f: 3 }, { f: 3 }, { f: 3 } ]</span>
console<span class="token punctuation">.</span><span class="token function">dir</span><span class="token punctuation">(</span>arr1<span class="token punctuation">)</span><span class="token punctuation">;</span>

In this example, the original array arr0 remains unchanged because the callback assigns ent to a new object { f: 3 }, thus changing the reference rather than the object itself.

Understanding this behavior is crucial for developers to avoid unexpected issues. Javascript passes object references, not copies, and altering the reference within a function does not impact the original object. Instead, to modify the original array, ensure you manipulate the object’s properties directly.