最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript - Empty an ArrayObject while Passing by Reference Issue - Stack Overflow

programmeradmin0浏览0评论

to my understanding, both array and objects are Pass By Reference based on the memory address, so if I create another variable and point to the array/object, and mutate any of the values, another value should also be changed.

However, I don't quite understand how it works here. I am pointing to array1 and modifying array1 to empty, why the value at anotherArray does not change?

   var array1 = [1,2,3,4,5,6,7];  // Created array
   var anotherArray = array1;     // Referenced array1 by another variable
   array1 = [];                   // Empty the array
   console.log(anotherArray);  // Output [1,2,3,4,5,6,7]

I can understand the below example why the anotherArray bees [] empty because it is passed by reference, but why the anotherArray still output [1,2,3,4,5,6,7] for the above?

   var array1 = [1,2,3,4,5,6,7]; // Created array
   var anotherArray = array1; // Referenced array1 by another variable
   array1.length = 0; // Empty the array by setting length to 0
   console.log(anotherArray); // Output []

Thank you.

to my understanding, both array and objects are Pass By Reference based on the memory address, so if I create another variable and point to the array/object, and mutate any of the values, another value should also be changed.

However, I don't quite understand how it works here. I am pointing to array1 and modifying array1 to empty, why the value at anotherArray does not change?

   var array1 = [1,2,3,4,5,6,7];  // Created array
   var anotherArray = array1;     // Referenced array1 by another variable
   array1 = [];                   // Empty the array
   console.log(anotherArray);  // Output [1,2,3,4,5,6,7]

I can understand the below example why the anotherArray bees [] empty because it is passed by reference, but why the anotherArray still output [1,2,3,4,5,6,7] for the above?

   var array1 = [1,2,3,4,5,6,7]; // Created array
   var anotherArray = array1; // Referenced array1 by another variable
   array1.length = 0; // Empty the array by setting length to 0
   console.log(anotherArray); // Output []

Thank you.

Share Improve this question asked Dec 18, 2021 at 20:09 cHappinesscHappiness 634 bronze badges 4
  • 1 In the first sample you are not modifying the array that array1 refers to, you are reassigning what array1 refers to. In the second sample you are modifying the array that array1 refers to – UnholySheep Commented Dec 18, 2021 at 20:11
  • What is the difference between reassigning vs modifying in the above examples? Thanks – cHappiness Commented Dec 18, 2021 at 20:16
  • In order the relationship to exist, both arrays should coexist. If you remove or redefine one of them the relationship goes puff.. – Redu Commented Dec 18, 2021 at 20:17
  • 1 There's no such thing as pass by reference in JS, everything is passed by value. It just so happens that for objects/arrays, the value itself is a reference. When you do array1 = [], you're simply replacing the value. – Lennholm Commented Dec 18, 2021 at 20:27
Add a ment  | 

5 Answers 5

Reset to default 3

Assigning to a variable never changes the object that the variable previously had as value.

Objects -- such as arrays -- only change when you mutate them, either through calling a method that does this, or by setting a property.

Here is a visualisation of your first script:

var array1 = [1,2,3,4,5,6,7] results in this:

  array1
   ↓
  ┌──────┬───┬───┬───┬───┬───┬───┬───┐
  │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
  ├──────┼───┼───┼───┼───┼───┼───┼───┤
  │  7   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
  └──────┴───┴───┴───┴───┴───┴───┴───┘

After var anotherArray = array1 we have this:

  array1
   ↓
  ┌──────┬───┬───┬───┬───┬───┬───┬───┐
  │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
  ├──────┼───┼───┼───┼───┼───┼───┼───┤
  │  7   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
  └──────┴───┴───┴───┴───┴───┴───┴───┘
   ↑
  anotherArray

Then array1 = [] will create a new array: so there are now two arrays. It also makes array1 a reference for the newly created array:

  array1
   ↓
  ┌──────┐
  │length│
  ├──────┤
  │  0   │
  └──────┘

  ┌──────┬───┬───┬───┬───┬───┬───┬───┐
  │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
  ├──────┼───┼───┼───┼───┼───┼───┼───┤
  │  7   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
  └──────┴───┴───┴───┴───┴───┴───┴───┘
   ↑
  anotherArray

In the second script the assignment to the length property (actually a setter) will mutate the array. There is no new array created, and the values 1,2,3,4,5,6,7 are lost:

  array1
   ↓
  ┌──────┐
  │length│
  ├──────┤
  │  0   │
  └──────┘
   ↑
  anotherArray

For your first example, you are actually making a reassignment to array1 as an empty array (and now they are pointing to 2 different arrays in the memory), hence the anotherArray remains unchanged.

 var array1 = [1,2,3,4,5,6,7];  // Created array
 var anotherArray = array1;     // Referenced array1 by another variable
 array1 = [];                   // Empty the array
 console.log(anotherArray);  // Output [1,2,3,4,5,6,7]

In this case, you are actually modifying the array by assigning it's length to 0. since array1 refers to it, it impacts on him as well since they are referring the same array in the memory.

  var array1 = [1,2,3,4,5,6,7]; // Created array
  var anotherArray = array1; // Referenced array1 by another variable
  array1.length = 0; // Empty the array by setting length to 0
  console.log(anotherArray); // Output []

The line

array1 = [];

does not modify the array object previously assigned to array1. It assigns a new (empty) array to the variable; it's not like invoking an operation on the object assigned to array1.

To explain it in other words, assume array1 was the only variable referring the previously assigned array object ([1,2,3,4,5,6,7]). Upon execution of that line (which is a statement, btw) you got lost of the previously assigned array; and it would be garbage collected some time later. This is all because the assignment operator is used here and they way its operational semantics is defined in JavaScript.

What is more, your are misusing the concept of pass by reference here (a.k.a. call by reference); which is a concept that relates to how values are passed to arguments of functions calls (or sub routines/procedures, if you prefer speaking of sub routines/procedures rather than functions).

In the assignment operator, a = x, the right-hand side is evaluated as an expression (x) and the resulting value is assigned to a.

This implies that a never “references” x.

Thus both a = b and a = [] result in a being re-assigned. It is irrelevant if the right-hand side is a variable (that is evaluated) or an empty array literal:

var b = [1,2,3] // create and assign array #1
var a = b
// ^— a is assigned the result of evaluating b
// after this assignment a and b “refer to” (read: evaluate to) the same object..
// b -> [1,2,3] #1
// a -> [1,2,3] #1

a.pop()
// ^— modify array object (a.length = 0 would empty the array)
// ..and since a and b refer to THE SAME ARRAY..
// b -> [1,2] #1
// a -> [1,2] #1

var a = [] // create and assign array #2
// ^— a is assigned the result of evaluating []
// after re-assignment both a and b refer to different array objects..
// (the assignment did not alter mutate the original array)
// b -> [1,2] #1
// a -> []    #2

a.push(3)
// ^— modify array object
// ..and since a and b refer to DIFFERENT ARRAYS..
// b -> [1,2] #1
// a -> [3]   #2

Calling functions works the exact same way as assignments and there is no “call by reference” in JavaScript. The values that result from the evaluation of expressions are supplied as arguments. JavaScript has Call by (Object) Sharing semantics.

tldr: there is no need to talk about “references” in Javascript here, as they add needless confusion and are not even defined (in this manner) in the specification!

In the first instance you're not actually updating the object that is referenced by array1. You're replacing the value under the variable name array1. anotherArray is pointing to the value in memory that was the previous value held in array1.

In the second example you're actually updating the underlying value that array1 and anotherArray are both pointing to

发布评论

评论列表(0)

  1. 暂无评论