EFH
EFH

Reputation: 441

Referencing Arrays in Javascript

I've got what may be a stupid question. In the code below, the function doStuff appears to reassign myArray to an empty array, but when tried it in the console, myArray is still [2,3,4,5].

var myArray = [2, 3, 4, 5];
function doStuff(arr) {
   arr = [];
};

doStuff(myArray);
console.log(myArray)// => [2,3,4,5]

Further, a function that modifies the array seems to work fine. For example:

 function changeSecondIndex(arr){
      arr[2] = 25;
 }

 changeSecondIndex(myArray)
 console.log(myArray) // => [2,3,25,5]

Could someone please help me understand what's going on here? Thanks.

Upvotes: 7

Views: 632

Answers (7)

konkked
konkked

Reputation: 3231

Objects are passed by reference in JavaScript, when you call the function in your first example the parameter arr is a reference to the object that is passed when the function is invoked

var myArray = [2, 3, 4, 5];
function doStuff(arr) {
   //arr is a variable that contains the first parameter used to invoke the 
   //function, if the variable is an object then it is passed by reference
   //
   //Here you are assigning the variable "arr" the value of a new array
   arr = [];
};

doStuff(myArray);
console.log(myArray)// => [2,3,4,5]

In the second example you are modifying the passed object, everything is still being passed the same way, difference is you are acting on the object that was passed rather than assigning the variable a new value.

 function changeSecondIndex(arr){
      //Acting on index 2 of the passed array and setting the value to 25
      arr[2] = 25;
 }

 changeSecondIndex(myArray)
 console.log(myArray) // => [2,3,25,5]

If you wanted to do something similar to what you are trying to do in the first example could have some sort of object that contains a state with your variables in it

var workingVars= {arr: [2, 3, 4, 5]};
function doStuff(env) {
   // here you are assigning a new empty array to arr property of 
   // passed parameter
   env.arr = [];
};
doStuff(workingVars);
console.log(workingVars.arr)// => []

Upvotes: 2

KpTheConstructor
KpTheConstructor

Reputation: 3291

To understand why this is happening you must first remember that an Array in Javascript is an object . The reason your arr = [] is taking no affect on your global declaration is for the following :

Reason 1 :

arr = [] does not clear an array , it just creates a new array object in memory no matter what .

So in your function :

function doStuff(arr) {
   arr = [];
};

doStuff(myArray)

you are just taking in myArray and making a new empty version of it in a local scope which leads to reason 2 .

Reason 2 :

Any new object / variable declared in a function is confined to the local scope of that function

so :

function doStuff(arr) {
   arr = [];
};


doStuff(myArray) //logs [1,2,3,4]

arr = [] was destroyed at the closing bracket of doStuff function an cannot exist on the outside .

Reason 3 :

function doStuff(arr){

 arr[2] = 25;

}

doStuff(myArray)

This works because you're accessing myArray in arr variable and modifying a property off myArray object, this is perfectly normal in javascript.

In short : = operator assigns , re-assigns , and creates ...

arr = [] is an assignment to new myArray object within your function and is also trapped in the scope of your function .

arr[2] = 25 accesses myArray object temporarily and re-assigns a property .

Hope this helps..

Upvotes: 0

Redu
Redu

Reputation: 26161

You don't need a function and arguments to experiment this. In JS [] and {} are object creation patterns (literal) and breaks the referral. Let's see...

var a = [1,2];
var b = [2,4];
var c = a; // c references a array.
var d = b; // d references b array
a.length = 0; // a becomes []
b = []; // b becomes []
console.log(c); // [] c still references a
console.log(d); // [2,4] d is no more a reference to b

Of course the same applies to the objects;

var o1 = {x:1, y:2};
var o2 = {x:2, y:4};
var p1 = o1; // p1 references o1
var p2 = o2; // p2 references o2
delete o1.x;
delete o1.y;
console.log(o1); // Object {}
console.log(p1); // Object {} p1 still references o1
o2 = {};
console.log(o2); // Object {}
console.log(p2); // Object {x: 2, y: 4} p2 is no more a reference to o2

Upvotes: 1

gen_Eric
gen_Eric

Reputation: 227260

Arrays are passed by reference in JavaScript. So, in your doStuff and changeSecondIndex functions, the arr parameter contains a reference to myArray.

In changeSecondIndex, you're using that reference to access and update a property of the array. That works fine, as you can see. But in doStuff, what's actually happening is that you are setting arr to a new array. What that does is remove the fact that arr was a reference to myArray and sets it to a new blank array. That's why myArray is not modified.

Upvotes: 3

Akshat Mahajan
Akshat Mahajan

Reputation: 9846

Javacript arrays are passed by reference, which means they can be modified within functions. This is why your second code snippet works.

Your first code snippet, however, simply declares a new variable arr within the scope of the function. It does not overwrite the old variable name, it merely removes your ability to reference the global variable you passed in.

Once that function exits, the new variable arr goes out of scope, and the name binding falls back to the global variable you declared previously.

That's why doStuff() does not modify the original array - because you were actually declaring a brand new array that just happened to share the same name within the scope of the function.

Upvotes: 3

Nenad Vracar
Nenad Vracar

Reputation: 122047

Your code is creating new empty array, instead you can empty existing array with length = 0

var myArray = [2, 3, 4, 5];
function doStuff(arr) {
   arr.length = 0;
};

doStuff(myArray);
console.log(myArray)

Upvotes: 4

swipeales
swipeales

Reputation: 127

You have defined global var myArray. And then you want to access this global array and change it in function. Yes it will overwrite global array, but only when you specific function. in your case function doStuff().

If you don't call doStuff(), it will keep global inicialization values!

Upvotes: -4

Related Questions