Reputation: 441
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
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
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
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
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
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
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
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