This question already has answers here:
Copy array by value
(39 answers)
Closed 4 years ago.
I found a really weird (for me) problem
I have this global variable ARRAY
var A = [1,2,3,4]
then inside a function, I made local var and assign previous global var to it
function someFunc() {
var X = A;
}
I then made another local Var and assign it with the first local var's value
var Y = X;
I then push a new value to Y
Y.push(6);
but the, the new value (6) didn't only pushed to Y, but also to the 2 original array (X and A). What happened? Doesn't it supposed to only change Y?
Please help, thank you.
Here is my full code:
var A = [1,2,3,4];
function someFunc(){
var X = A;
var Y = X;
Y.push(6);
console.log(A);
console.log(X);
console.log(Y);
}
$("#test").click(function(){
someFunc();
});
as you can see, it is triggered by clicking on element with id #test.
All three console.log, even thought represent different variable, it return the same result, ARRAY with 6 on it
Edit. Yes there is a similar question to this, but even though the problem is similar and the solution is identical, but the initial understanding is what different. In my question, I initially asked "Why", because I am not aware of those variable actually 'refer' to same array instead of 'assigning', so I have no idea if I should search for how to assign instead of refer, since I assumed that using = means assigning, sorry
What happens is that you do not copy the array you just reference it. You can use the method slice to create a copy of it:
var X = A.slice();
Do mind that you can use this approach only with primitive values. Check this if you need to deal with objects How do you clone an Array of Objects in Javascript?
Your arrays aren't cloned: assigning a variable does not clone the underlying object.
You can shallow-clone an array using the slice method:
var cloned = original.slice();
But array and object items within the array are not cloned using this method. Numbers and strings are cloned, however, so this should work fine for your case.
An array in JavaScript is also an object and variables only hold a reference to an object, not the object itself. Thus both variables have a reference to the same object.
Related
So array in javascript are assigned by references so for example
let a = [1,2,3];
let b = a;
a = [];
console.log(b);
Shouldn't it print empty array as a is assigned to empty array and b and a are point to same.
I know that such behavior might seem weird. However, as other writers already mentioned, what happens is that by writing ‘a = []’ you actually assigned ‘a’ a new reference (i.e. you are not manipulating the ‘old’ array any more), and ‘b’ will hold an old reference to a memory location where ‘old’ array was initially assigned and break a relationship with ‘a’. Hence, there will now exist 2 references instead of an initial 1.
I've searched about call by reference on javascript but still am confused.
consider this code.
let arr = [];
let temparr = [2,3,4];
arr = temparr;
temparr.push(5);
console.log(arr); //[2,3,4,5]
console.log(temparr); //[2,3,4,5]
let arr2 = [];
let temparr2 = [2,3,4];
arr2 = temparr2;
temparr2 = [1,2];
console.log(arr2); //[2,3,4]
console.log(temparr2); /[1,2]
For the first case, arr gets affected by temparr due to arr = temparr, however, in the second example, arr2 does not get affected by modification in temparr2. My question is,
In the first example, Why in the first place is arr getting affected by the modification of temparr? Is this in the line of call by reference? If so, on what occasions does it trigger such operation?
In the second example, the only difference is that i did not use push but assign new array to modify the temparr2. However this time arr2 did not get affected. What is the difference with the first example?
Thank you very much
Your question has less to do with how arguments are passed (everything is passed by Value all the time in JavaScript, by the way) and more to do with how Objects are stored.
In your first example, the line most relevant to your question is this:
arr = temparr;
Here, you are setting up a second variable to hold the same value as the first, but Object variables don't hold the Object, they hold the location in memory to where the object is stored. So, after that line, you have two variables that both point to the same, one underlying object. If either one of them modifies that underlying object, the other will see the same thing because they both point to only one object.
In your second example, you start out in a similar way with:
arr2 = temparr2;
Which, again, sets you up to have two variables that point to the same one, underlying object. But, then you do this:
temparr2 = [1,2];
Which doesn't modify the one underlying object, it simply reassigns the second variable to a different object, and now the two variables don't point to the same thing anymore.
It's really no different than saying:
x = 7;
and then saying:
x = 8;
The old value in x goes away and there's an entirely new value stored.
If you wanted to modify the underlying array, you would do that via the Array API, for example:
temparr2.splice(2,1); // Delete one item at index position 2
This is why the array was modified when you used .push() in the first example - - you were working on the object, not reassigning the variable.
I was trying to understand some javascript and found some quite unexpected behavior. Not knowing much about this language I wanted to find out what this behavior is called so that I can read about it formally.
Here's an example of the behavior:
var test={'x':2};
var test2=test;
test2.sourceLinks = [];
console.log('test',test);
console.log('test2',test2);
To my amazement, I found that modifying the 2nd variable somehow modifies the first as well. The variable "test" will also have an attribute .sourceLinks = []. Do I understand what's happening correctly, and if so, what's the formal term for this behavior?
I found that the answer to this is covered in How do I correctly clone a JavaScript object? after I posted it, although that covered more than I was asking about.
Behavior is called creating a reference. When variable assigned is an object actually it is not copied, rather the result of assignment is a new reference (pointer) to the object.
This doesn't happen with primitive types:
number,
string,
boolean,
null,
undefined.
But happens with all object types:
object,
Array,
function.
This difference is significant in javascript. When some value should be passed to another scope and it might be modified there it should be passed be reference.
function main(){
var x = 1;
modify(x);
console.log(x);//x remains 1
}
function modify(arg){
arg = 10;
}
Whereas when it is passed as a field of an object, it can be modified via reference to an object:
function main(){
var o = {x : 1};
modifyObj(o);
console.log(o);//o.x now equals 10
}
function modifyObj(arg){
arg.x = 10;
}
It's holding the reference.
When you assign object/array/function to another object/array/function it'll assign reference instead of value.
To overcome this you have to clone it
When declaring a variable in Javascript you are creating an object in memory and the variable in the scope is a pointer to that memory object.
In your example both variables (test and test2) are pointing to the same object. Hence, when you modify the the either variable pointer, it is modifying the same object in memory.
This question already has answers here:
Is JavaScript a pass-by-reference or pass-by-value language?
(33 answers)
Closed 7 years ago.
I was curious, so I tried this out:
var test = example = 5;
Now, this is a somewhat common way of defining things...
(for instance in node, module.exports = exports = ...)
The above be equivalent to:
example = 5;
var test = example;
Now, if variables don't actually hold a value, but are rather references to values in the memory, when I change example, if test is referencing example which is referencing a value, shouldn't test also have that same value as example? Lets try it:
var test = example = 5;
example = 7;
console.log(test, example);
... Now, the output isn't really what I expected, due to what I put above.. You get this:
5 7
But how is test still 5 if test is referencing example, and example is now 7? Shouldn't they both be 7?
EDIT Tried using Objects instead... But I get the same behavior:
var test = example = {"hello":"world", "foo":"bar"};
example = {"test":"example"};
console.log(test, example);
This outputs:
Object {hello: "world", foo: "bar"}
Object {test: "example"}
So, they're still not the same like I expected.
var a = {}; // There is one object in memory
var b = a; // now both `b` and `a` refer to that object
a = {}; // now we create another object and put a reference to it to an `a`
// we haven't changed `b` so it refers to the former object
And to summarize: in JS you cannot change the value of another variable. Value of variables a and b in the example above is a reference, not the object itself. And the only way to change the value of the variable - is to re-assign another value to it. So you cannot change the value of a variable indirectly in JS, at all (?).
When speaking about java script, variables can accept multiply values. JavaScript is a very 'forgiving' language let's call it like this.
So, if you said for example:
var test = example = 5;
test would still be 5, because test is now given the value of 5. test is but a reference in this case to example.
the actual value of example, is 7.
example = 7;
So yes, it's a bit odd, But javascript behaves a bit differently then other programming languages.
I'm coming to javascript from C background. In javascript, when I use the assignment operator to assign one object to another, does it copy the values from one to the another, or do they both now point to the same data?. Or does the assignment operator do anything in this case?
function point_type()
{
this.x = 0;
this.y = 0;
}
var pnt1 = new point_type();
var pnt2 = new point_type();
pnt1.x = 4;
pnt1.y = 5;
pnt2 = pnt1;
pnt1.x = 8;
pnt2.y = 9;
In the example above, does pnt2.x now equal 8, or does it still equal 4, or does it still equal 0?
Yes, I realize I can test this myself, and I will be doing that while I wait for the community to come up with an answer. However, I'm hoping the answer to my question will go one step past just answering this one example and might shine some light on how javascript objects work and some best practices.
Follow up question:
The answer seems to be that the reference is copied. pnt2 and pnt1 now point to the same data. Is it possible to set up my object so that the values are copied? How is this usually accomplished in javascript? Clearly I don't want to set each attribute individually every time I need to copy this object.
Whenever I need to copy one object to another in JS, I just cast it to a primitive:
var newObject = JSON.stringify(oldObject);
Then when I need to use it:
var evenNewerObj = JSON.parse(newObject);
Hope this helps someone.
In JavaScript, primitive types are copied by value and reference types are copied by reference. More info here: http://docstore.mik.ua/orelly/web/jscript/ch09_03.html
It equals 8.
pnt2 = pnt1
That statement is pointing the pnt2 object to the pnt1 object so any modification you do to pnt1 will show up in pnt2.
Given the object you showed in your example, it is setting a reference to the object. If it were a primitive type (number, date) then it would copy the object.