Why does changing one array alters the other? - javascript

Consider this tiny bit of javascript code:
var a = [1, 2, 3],
b = a;
b[1] = 3;
a; // a === [1, 3, 3] wtf!?
Why does "a" change when I update "b[1]"? I've tested it in Firefox and Chrome. This doesn't happen to a simple number for example. Is this the expected behaviour?
var a = 1,
b = a;
b = 3;
a; // a === 1 phew!

It's the same array (since it's an object, it's the same reference), you need to create a copy to manipulate them separately using .slice() (which creates a new array with the elements at the first level copied over), like this:
var a = [1, 2, 3],
b = a.slice();
b[1] = 3;
a; // a === [1, 2, 3]

Because "a" and "b" reference the same array. There aren't two of them; assigning the value of "a" to "b" assigns the reference to the array, not a copy of the array.
When you assign numbers, you're dealing with primitive types. Even on a Number instance there's no method to update the value.
You can see the same "they're pointing to the same object" behavior with Date instances:
var d1 = new Date(), d2 = d1;
d1.setMonth(11); d1.setDate(25);
alert(d2.toString()); // alerts Christmas day

In addition to the other answers, if you want a copy of an array, one approach is to use the slice method:
var b = a.slice(0)

All Javascript objects are passed by reference - you would need to copy the entire object, not assign it.
For arrays this would be simple - just do something like:
var a = [1, 2, 3];
var b = a.slice(0);
where slice(0) returns the array from offset 0 to the end of the array.
This link has more info.

There is a difference between Value types and Reference types.
Basicly Value types are stored on the computers "Stack" directly which means that you actualy have the "Value" and not what is called a Pointer/Reference.
A Reference Type on the other hand, does not hold the actual value of the object/variable but instead it points ( references ) to where you can find the value.
Thus when you say "My Reference Type B points to what Reference Type A points to", you actually have two variables pointing in the same direction and when you interact with either of them and change something, both will be pointing to the changed place, since the pointed to the same place from the begining.
In your other case you say "Hey, copy the value in variable A to variable B" and thus you have the values on seperate places which means that any change to either of them will not affect the other.

Because arrays are references to actual place where they are stored.

the statement x = y is the only special one here, it means "point the variable x at the object y.
Pretty much every other operation is an operation which changes the object referred to by x
b = a;
b[1] = 3;
So, your first statement points the variable b at the array also referred to as a
Your second statement alters the array pointed to by b (and also by a)

Assigning an array does not create a new array, it's just a reference to the same array. Numbers and booleans are copied when assigned to a new variable.

Related

Why manipulating a duplicated array reflects the origined array too [duplicate]

Consider this tiny bit of javascript code:
var a = [1, 2, 3],
b = a;
b[1] = 3;
a; // a === [1, 3, 3] wtf!?
Why does "a" change when I update "b[1]"? I've tested it in Firefox and Chrome. This doesn't happen to a simple number for example. Is this the expected behaviour?
var a = 1,
b = a;
b = 3;
a; // a === 1 phew!
It's the same array (since it's an object, it's the same reference), you need to create a copy to manipulate them separately using .slice() (which creates a new array with the elements at the first level copied over), like this:
var a = [1, 2, 3],
b = a.slice();
b[1] = 3;
a; // a === [1, 2, 3]
Because "a" and "b" reference the same array. There aren't two of them; assigning the value of "a" to "b" assigns the reference to the array, not a copy of the array.
When you assign numbers, you're dealing with primitive types. Even on a Number instance there's no method to update the value.
You can see the same "they're pointing to the same object" behavior with Date instances:
var d1 = new Date(), d2 = d1;
d1.setMonth(11); d1.setDate(25);
alert(d2.toString()); // alerts Christmas day
In addition to the other answers, if you want a copy of an array, one approach is to use the slice method:
var b = a.slice(0)
All Javascript objects are passed by reference - you would need to copy the entire object, not assign it.
For arrays this would be simple - just do something like:
var a = [1, 2, 3];
var b = a.slice(0);
where slice(0) returns the array from offset 0 to the end of the array.
This link has more info.
There is a difference between Value types and Reference types.
Basicly Value types are stored on the computers "Stack" directly which means that you actualy have the "Value" and not what is called a Pointer/Reference.
A Reference Type on the other hand, does not hold the actual value of the object/variable but instead it points ( references ) to where you can find the value.
Thus when you say "My Reference Type B points to what Reference Type A points to", you actually have two variables pointing in the same direction and when you interact with either of them and change something, both will be pointing to the changed place, since the pointed to the same place from the begining.
In your other case you say "Hey, copy the value in variable A to variable B" and thus you have the values on seperate places which means that any change to either of them will not affect the other.
Because arrays are references to actual place where they are stored.
the statement x = y is the only special one here, it means "point the variable x at the object y.
Pretty much every other operation is an operation which changes the object referred to by x
b = a;
b[1] = 3;
So, your first statement points the variable b at the array also referred to as a
Your second statement alters the array pointed to by b (and also by a)
Assigning an array does not create a new array, it's just a reference to the same array. Numbers and booleans are copied when assigned to a new variable.

value of duplicated array row changing original row [duplicate]

Consider this tiny bit of javascript code:
var a = [1, 2, 3],
b = a;
b[1] = 3;
a; // a === [1, 3, 3] wtf!?
Why does "a" change when I update "b[1]"? I've tested it in Firefox and Chrome. This doesn't happen to a simple number for example. Is this the expected behaviour?
var a = 1,
b = a;
b = 3;
a; // a === 1 phew!
It's the same array (since it's an object, it's the same reference), you need to create a copy to manipulate them separately using .slice() (which creates a new array with the elements at the first level copied over), like this:
var a = [1, 2, 3],
b = a.slice();
b[1] = 3;
a; // a === [1, 2, 3]
Because "a" and "b" reference the same array. There aren't two of them; assigning the value of "a" to "b" assigns the reference to the array, not a copy of the array.
When you assign numbers, you're dealing with primitive types. Even on a Number instance there's no method to update the value.
You can see the same "they're pointing to the same object" behavior with Date instances:
var d1 = new Date(), d2 = d1;
d1.setMonth(11); d1.setDate(25);
alert(d2.toString()); // alerts Christmas day
In addition to the other answers, if you want a copy of an array, one approach is to use the slice method:
var b = a.slice(0)
All Javascript objects are passed by reference - you would need to copy the entire object, not assign it.
For arrays this would be simple - just do something like:
var a = [1, 2, 3];
var b = a.slice(0);
where slice(0) returns the array from offset 0 to the end of the array.
This link has more info.
There is a difference between Value types and Reference types.
Basicly Value types are stored on the computers "Stack" directly which means that you actualy have the "Value" and not what is called a Pointer/Reference.
A Reference Type on the other hand, does not hold the actual value of the object/variable but instead it points ( references ) to where you can find the value.
Thus when you say "My Reference Type B points to what Reference Type A points to", you actually have two variables pointing in the same direction and when you interact with either of them and change something, both will be pointing to the changed place, since the pointed to the same place from the begining.
In your other case you say "Hey, copy the value in variable A to variable B" and thus you have the values on seperate places which means that any change to either of them will not affect the other.
Because arrays are references to actual place where they are stored.
the statement x = y is the only special one here, it means "point the variable x at the object y.
Pretty much every other operation is an operation which changes the object referred to by x
b = a;
b[1] = 3;
So, your first statement points the variable b at the array also referred to as a
Your second statement alters the array pointed to by b (and also by a)
Assigning an array does not create a new array, it's just a reference to the same array. Numbers and booleans are copied when assigned to a new variable.

Value of variable not getting updated after assignment

var a = 2;
var b = a;
console.log( b ); //2
a= 5;
console.log( b ); //2
Q: Why variable 'b' is getting value 2 even when variable 'a' is assigned a different value
console.log(b) returns 2 because when you access a primitive type you work directly on its value.
Cause numbers are immutable.
Changing an immutable value, replaces the original value with a new value, hence the original value is not changed (thats why b = 2).
If you need a reference, use object and/or arrays
var a ={value: 2}, b = a
a.value = 3 // also changes the value of be, since it can mutate
In javascript, primitives (number, bool, string) are assigned by value, only objects are assigned by reference.
In Javascript, integers are immutable. It means that the object's value once assigned cannot change. When you do
a=5;
b=a;
It is true that both are names of the same object whose value is 5.
Later when you do -
a=2
It assigns the reference a a new object whose value is 2. So essentially a now points to a new object. Ans both objects exist.
For a better understanding you can refer to this link
When doing Assignment of primitive values in javascript:
It's important to point out that this assignment does not tie a and b together. In fact all that happened was that the value from a was copied into b, so when we go to change a we don't have to worry about affecting b. This is because the two variables are backed by two distinct memory locations – with no crossover.
In brief way:
When you assign b = a
Actually you didn't copy the reference of a variable and make b point to the same variable location in memory.
You only copy the value of a variable and put it in new variable b with different memory location.

Assign value to the array passed to a function

var arrN = [1, 2, 3];
function init(arr){
arr = [];
console.log(arrN) //output [1, 2, 3], expect []
}
init(arrN);
When using splice or push methods the array passed to a function is being modified. So I am trying to understand what is happening when using assignment operator, why it's not changing the array? is it creating the local var of the passed array?
Any help will be appreciated!
You need to distinguish between the variable and the actual object (the array). splice and push are changing the object.
arr = [] is just changing the variable, the old object just stays as it is.
There is a difference in assigning a different object to a variable or mutating the object currently referenced by a variable.
(Re)assigning
When you do an assignment like:
arr = []; // or any other value
... then the value that arr previously had is not altered. It is just that arr detaches from that previous value and references a new value instead. The original value (if it is an object) lives on, but arr no longer has access to it.
Side note: if no other variable references the previous value any more, the garbage collector will at some point in time free the memory used by it. But this is not your case, since the global variable arrN still references the original value.
Mutating
It is another thing if you don't assign a value to arr, but apply instead a mutation to it, for instance with splice, push, pop, or an assignment to one of its properties, like arr[0] = 1 or arr[1]++. In those cases, arr keeps referencing the same object, and the changes are made to the object it references, which is visible to any other variable that references the same object, like arrN.
Clearing an array
Now if you want to clear the array that is passed to your function, you must avoid to make an assignment like arr = .... Instead, use methods that mutate the array in place:
arr.splice(0)
Or, alternatively:
arr.length = 0;
Now you have actually mutated the array, which is also the array referenced by arrN.
In JavaScript, particularly when working with objects the assignment operator (=) has three jobs.
Assignment
Creating a new reference if the right side is an object.
Breaking any previous referencing and creating multiple assignments if both sides are objects.
Such as;
var a = [1,2,3], // a is assigned an array
b = a; // b is assigned just a reference to a
a = ["a","b","c"]; // b to a referral is now broken
// a is assigned with ["a","b","c"]
// b is assigned with [1,2,3]
same would apply if it was done in reverse order;
var a = [1,2,3], // a is assigned an array
b = a; // b is assigned just a reference to a
b = ["a","b","c"]; // b to a referral is now broken
// b is assigned with ["a","b","c"]
// a keeps it's existing assignment as [1,2,3]
Your are passing arrN to the console instead of passing arr. Also, you just call a function by its name, not by the keyword function. Here is the corrected code:
var arrN = [1, 2, 3];
function init(arr){
arr = [];
console.log(arr)
}
init(arr);
You have also declared init() with an argument arr, which is not needed in this case. What ever the value you pass to init(), the value of arr will be [] because you are reassigning it in the function.

Prototype function replacing the original object [duplicate]

Why can I do this:
Array.prototype.foo = function() {
this.splice(0, this.length);
return this.concat([1,2,3]);
}
But I can't do this:
Array.prototype.foo = function() {
return this = [1,2,3];
}
Both functions destroy the value of this and change it to [1,2,3] but the second one throws the following error: Uncaught ReferenceError: Invalid left-hand side in assignment
I suspect it's because allowing assignment means I could potentially change the array to something else (like a string), but I'm hoping someone out there knows for sure and/or has a more detailed explanation.
You're confusing objects with references.
An array is an object, when you use a literal like [1,2,3] you're making a new array.
A variable name like this or a is a reference to an object. If it helps, imagine an object as a person, and the reference as their nickname. You can have more than one reference to the same object, for example:
var a = [1,2];
var b = a;
b.push(3);
alert(a.length); // Gives "3"
Imagine if you had a friend named Sarah. You also sometimes call her "Ace". If Sarah gets a haircut one day, Ace has a haircut too, because "Sarah" and "Ace" are both different names for the same person.
If you use a mutating array method like a.push or a.splice (concat however is not one!), you change the existing Array object, and a still refers to the same object. This is like getting a hair cut - you may look different, but you're still the same person.
When you assign a reference to a new value, with a = [1,2,3], you're creating a new array, and changing a to refer to it. This is like finding a new friend with different hair, and deciding to call her Ace instead.
Now this is a special name generated by Javascript. It's not a given name like Sarah, but more of a title, like "mother". Your mother can get a new haircut, but you can't get a new mother. Likewise, you can't change what this refers to from inside a function.
It's not permitted to assign a value to this within a function. Suppose that you could do this, and your code looked something like:
Array.prototype.foo = function() {
return this = [1, 2, 3];
}
var a = ["beans", "rice"];
a.foo();
// a now points to an object containing [1, 2, 3]
Now, what if you did this:
var a = ["beans", "rice"];
var b = a; // b refers to the same object as a
b.foo();
// what does b refer to now? how about a?
The act of calling a function .foo() on an object should not change the identity of the object. This would be very confusing for the caller if b suddenly started referring to a different object than a simply because some method was called.
You are not allowed to re-assign this. Because the this value associated with an execution context is immutable.
Is it possible to change the value of this? Not by assignment, you cannot assign a value to this
Your case:
Array.prototype.foo = function() {
this.splice(0, this.length);
return this.concat([1,2,3]);
}
But I can't do this:
Array.prototype.foo = function() {
return this = [1,2,3];
}
When you modify the prototype adding method foo(), the first part makes the array become empty, equals to reassign its instance.
For example to var a = []
Then in the return value:
return this.concat([1,2,3]);
Remember that concat does not destroys an array, it creates a new array and returns it
Given a = ['x'] and b = ['y'], c = a.concat(b) results in c = ['x','y'], and a and b remain the same as they were
Now since you are doing this inside the array
a=['a','b','c']
then you call a.foo();, inside a will get equal a=[], with this.splice(0, this.length); then will concatenate [ ] with [1,2,3]
So if I say just a.foo(), in fact nothing happens outside if I do not assign the result to something, just a remains empty.
If a is assigned to something
c = a.foo()
then c will be [1,2,3], and a still empty [ ]
In the second part, this = [1,2,3]
It is possible to change the value of this?, not by assignment, you cannot assign a value to this

Categories

Resources