4

I want to know if javascript does shallow or deep copy when copying objects.

const a = ['value1', 'value2'];
const b = ['value3', 'value4'];
const new_ab = [a, b];

new_ab are going to have new allocated values or a reference? If it is a deep copy, how can I make it to be swallow? Thanks.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Mateus Felipe
  • 1,071
  • 2
  • 19
  • 43
  • 1
    `a` and `b` are references to the arrays, so `new_ab` will be a reference to an array containing those references. No objects are copied at all in the code you posted. – Pointy Dec 23 '15 at 17:52
  • 1
    You can check this very easily by mutating `new_ab[0]` and seeing what happens to `a`. – Blender Dec 23 '15 at 17:52
  • So, it's performatic to use the above code, as they are only references? – Mateus Felipe Dec 23 '15 at 18:02

1 Answers1

1

As alluded in the comments, JavaScript operates entirely on references, the only exception being that primitive values are kept on the stack and a program does not therefore require a reference to access them. In your example all variable declarations create new values - each an instance of Array - however what is returned from declaring an array is a reference, not the array itself. For example, [1, 2] is an array of values (integers), but [a, b] is an array of references.

So... nothing is copied. We can demonstrate this by placing an object as an element of an array and inspecting that a previously assigned property is still accessible through the new 'parent' array.

(And to answer your question in the comments, yes, your example is more performant than if you (or JavaScript) were to copy values.)

'use strict';

const arrayOne = [];

arrayOne.someProperty = "This string is a property of `arrayOne`, " +
                        "accessed via the reference to it in `arrayTwo`."

const arrayTwo = [arrayOne];

span.innerHTML = arrayTwo[0].someProperty;
<span id="span"></span>
sdgluck
  • 24,894
  • 8
  • 75
  • 90
  • 1
    *"the only exception being that primitive values are kept on the stack and a program does not therefore require a reference to"* How do you know that? Can you reference the spec? Also, how would this work with closures then? – Felix Kling Dec 23 '15 at 22:01
  • @FelixKling Not all primitive values are stored on the stack. The way these values are treated is an impl. detail over a requirement of the spec. When a primitive value is required by a closure the compiler will place that value on the heap. References are [here](https://www.quora.com/JavaScript-programming-language/With-JavaScript-functions-always-acting-as-closures-at-what-point-do-any-variables-get-allocated-to-the-stack-instead-of-the-heap) and [here](http://duartes.org/gustavo/blog/post/closures-objects-heap/), and although anecdotal are all I have without reading v8's source code. :) – sdgluck Dec 23 '15 at 22:35
  • Admittedly I am being liberal with the quoted statement, however the principle of storing primitive values on the stack is true of many OOP languages. When coercion and other such operations occur, or a value is referenced within a closure as you said, then this principle may be subverted. – sdgluck Dec 23 '15 at 22:38
  • That was basically my point: It's an implementation detail and it's not generally true, so the statement is not correct as it is. It's also not relevant to the question IMO. – Felix Kling Dec 23 '15 at 22:40
  • @FelixKling Fair enough. Thought it was an interesting tidbit! – sdgluck Dec 23 '15 at 22:42