This variable change from nowhere [duplicate] - javascript

I've written the following JavaScript:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
This code declares a variable myArray and sets it to an array value. It then declares a second variable copyOfMyArray and sets it to myArray.
It performs an operation on copyOfMyArray and then alerts both myArray and copyOfMyArray. Somehow, when I perform an operation on copyOfMyArray, it appears that the same operation is performed on myArray.
The code then does the same thing with a number value: It declares a variable myNumber and sets it to a number value. It then declares a second variable copyOfMyNumber and sets it to myNumber. It performs an operation on copyOfMyNumber and then alerts both myNumber and copyOfMyNumber. Here, I get the expected behavior: different values for myNumber and copyOfMyNumber.
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
I'm guessing that for some reason, the array is referred to by reference and the number by value, but why? How can I know what behavior to expect with other objects?

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.
Your comparison with the number example is not correct btw. You assign a new value to copyOfMyNumber. If you assign a new value to copyOfMyArray it will not change myArray either.
You can create a copy of an array using slice [docs]:
var copyOfMyArray = myArray.slice(0);
But note that this only returns a shallow copy, i.e. objects inside the array will not be cloned.

Well, the only possible answer — and the correct one — is that you're not actually copying the array. When you write
var copyOfArray = array;
you're assigning a reference to the same array into another variable. They're both pointing at the same object, in other words.

So everyone here has done a great job of explaining why this is happening - I just wanted to drop a line and let you know how I was able to fix this - pretty easily:
thingArray = ['first_thing', 'second_thing', 'third_thing']
function removeFirstThingAndPreserveArray(){
var copyOfThingArray = [...thingArray]
copyOfThingArray.shift();
return copyOfThingArray;
}
This is using the ... spread syntax.
Spread Syntax Source
EDIT: As to the why of this, and to answer your question:
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
The answer is that in JavaScript, arrays and objects are mutable, while strings and numbers and other primitives are immutable. When we do an assignment like:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray is really just a reference to myArray, not an actual copy.
I would recommend this article, What are immutable and mutable data structures?, to dig deeper into the subject.
MDN Glossary: Mutable

Cloning objects -
A loop / array.push produces a similar result to array.slice(0) or array.clone(). Values are all passed by reference, but since most primitive data types are immutable, subsequent operations produce the desired result - a 'clone'. This is not true of objects and arrays, of course, which allow for modification of the original reference (they are mutable types).
Take the following example:
const originalArray = [1, 'a', false, {foor: 'bar'}]
const newArray = [];
originalArray.forEach((v, i) => {
newArray.push(originalArray[i]);
});
newArray[0] = newArray[0] + 1;
newArray[1] = 'b';
newArray[2] = true;
newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
The operations run on the newArray indices all produce the desired result, except the final (object), which, because it is copied by reference, will mutate the originalArray[3] as well.
https://jsfiddle.net/7ajz2m6w/
Note that array.slice(0) and array.clone() suffers from this same limitation.
One way to solve this is by effectively cloning the object during the push sequence:
originalArray.forEach((v, i) => {
const val = (typeof v === 'object') ? Object.assign({}, v) : v;
newArray.push(val);
});
https://jsfiddle.net/e5hmnjp0/
cheers

The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));
console.log(clonedArray);
// [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy

In JS, operator "=" copy the pointer to the memory area of the array.
If you want to copy an array into another you have to use the Clone function.
For integers is different because they are a primitive type.
S.

Create a filter of the original array in the arrayCopy. So that changes to the new array won't affect original array.
var myArray = ['a', 'b', 'c'];
var arrayCopy = myArray.filter(function(f){return f;})
arrayCopy.splice(0, 1);
alert(myArray); // alerts ['a','b','c']
alert(arrayCopy); // alerts ['b','c']
Hope it helps.

Everything is copied by reference except primitive data types (strings and numbers IIRC).

You don't have any copies.
You have multiple variables holding the same array.
Similarly, you have multiple variables holding the same number.
When you write copyOfMyNumber = ..., you're putting a new number into the variable.
That's like writing copyOfMyArray = ....
When you write copyOfMyArray.splice, you're modifying the original array.
That isn't possible with numbers because numbers are immutable and cannot be modified,

You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.
function CopyAnArray (ari1) {
var mxx4 = [];
for (var i=0;i<ari1.length;i++) {
var nads2 = [];
for (var j=0;j<ari1[0].length;j++) {
nads2.push(ari1[i][j]);
}
mxx4.push(nads2);
}
return mxx4;
}

An array, or an object in javascript always holds the same reference unless you clone or copy. Here is an exmaple:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference
var obj = {
"name": "a"
}
var arr = [];
//we push the same object
arr.push(obj);
arr.push(obj);
//if we change the value for one object
arr[0].name = "b";
//the other object also changes
alert(arr[1].name);
For object clone, we can use .clone() in jquery and angular.copy(), these functions will create new object with other reference. If you know more functions to do that, please tell me, thanks!

For Arrays with objects you can change the use JSON.parse and JSON.strinigfy to change the type of the array to an object refrence to a string and then back to a array without having to worry about the original array
var array = [{name:'John', age:34, logs:'[]'}, {name:'David', age:43, logs:'[3]'}];
var array2 = JSON.parse(JSON.stringify(array)); // turn object to function output
array2[0].age++;
alert(JSON.stringify(array));
alert(JSON.stringify(array2));

Related

Javascript multidimensional array question [duplicate]

I've written the following JavaScript:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
This code declares a variable myArray and sets it to an array value. It then declares a second variable copyOfMyArray and sets it to myArray.
It performs an operation on copyOfMyArray and then alerts both myArray and copyOfMyArray. Somehow, when I perform an operation on copyOfMyArray, it appears that the same operation is performed on myArray.
The code then does the same thing with a number value: It declares a variable myNumber and sets it to a number value. It then declares a second variable copyOfMyNumber and sets it to myNumber. It performs an operation on copyOfMyNumber and then alerts both myNumber and copyOfMyNumber. Here, I get the expected behavior: different values for myNumber and copyOfMyNumber.
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
I'm guessing that for some reason, the array is referred to by reference and the number by value, but why? How can I know what behavior to expect with other objects?
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.
Your comparison with the number example is not correct btw. You assign a new value to copyOfMyNumber. If you assign a new value to copyOfMyArray it will not change myArray either.
You can create a copy of an array using slice [docs]:
var copyOfMyArray = myArray.slice(0);
But note that this only returns a shallow copy, i.e. objects inside the array will not be cloned.
Well, the only possible answer — and the correct one — is that you're not actually copying the array. When you write
var copyOfArray = array;
you're assigning a reference to the same array into another variable. They're both pointing at the same object, in other words.
So everyone here has done a great job of explaining why this is happening - I just wanted to drop a line and let you know how I was able to fix this - pretty easily:
thingArray = ['first_thing', 'second_thing', 'third_thing']
function removeFirstThingAndPreserveArray(){
var copyOfThingArray = [...thingArray]
copyOfThingArray.shift();
return copyOfThingArray;
}
This is using the ... spread syntax.
Spread Syntax Source
EDIT: As to the why of this, and to answer your question:
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
The answer is that in JavaScript, arrays and objects are mutable, while strings and numbers and other primitives are immutable. When we do an assignment like:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray is really just a reference to myArray, not an actual copy.
I would recommend this article, What are immutable and mutable data structures?, to dig deeper into the subject.
MDN Glossary: Mutable
Cloning objects -
A loop / array.push produces a similar result to array.slice(0) or array.clone(). Values are all passed by reference, but since most primitive data types are immutable, subsequent operations produce the desired result - a 'clone'. This is not true of objects and arrays, of course, which allow for modification of the original reference (they are mutable types).
Take the following example:
const originalArray = [1, 'a', false, {foor: 'bar'}]
const newArray = [];
originalArray.forEach((v, i) => {
newArray.push(originalArray[i]);
});
newArray[0] = newArray[0] + 1;
newArray[1] = 'b';
newArray[2] = true;
newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
The operations run on the newArray indices all produce the desired result, except the final (object), which, because it is copied by reference, will mutate the originalArray[3] as well.
https://jsfiddle.net/7ajz2m6w/
Note that array.slice(0) and array.clone() suffers from this same limitation.
One way to solve this is by effectively cloning the object during the push sequence:
originalArray.forEach((v, i) => {
const val = (typeof v === 'object') ? Object.assign({}, v) : v;
newArray.push(val);
});
https://jsfiddle.net/e5hmnjp0/
cheers
The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));
console.log(clonedArray);
// [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy
In JS, operator "=" copy the pointer to the memory area of the array.
If you want to copy an array into another you have to use the Clone function.
For integers is different because they are a primitive type.
S.
Create a filter of the original array in the arrayCopy. So that changes to the new array won't affect original array.
var myArray = ['a', 'b', 'c'];
var arrayCopy = myArray.filter(function(f){return f;})
arrayCopy.splice(0, 1);
alert(myArray); // alerts ['a','b','c']
alert(arrayCopy); // alerts ['b','c']
Hope it helps.
Everything is copied by reference except primitive data types (strings and numbers IIRC).
You don't have any copies.
You have multiple variables holding the same array.
Similarly, you have multiple variables holding the same number.
When you write copyOfMyNumber = ..., you're putting a new number into the variable.
That's like writing copyOfMyArray = ....
When you write copyOfMyArray.splice, you're modifying the original array.
That isn't possible with numbers because numbers are immutable and cannot be modified,
You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.
function CopyAnArray (ari1) {
var mxx4 = [];
for (var i=0;i<ari1.length;i++) {
var nads2 = [];
for (var j=0;j<ari1[0].length;j++) {
nads2.push(ari1[i][j]);
}
mxx4.push(nads2);
}
return mxx4;
}
An array, or an object in javascript always holds the same reference unless you clone or copy. Here is an exmaple:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference
var obj = {
"name": "a"
}
var arr = [];
//we push the same object
arr.push(obj);
arr.push(obj);
//if we change the value for one object
arr[0].name = "b";
//the other object also changes
alert(arr[1].name);
For object clone, we can use .clone() in jquery and angular.copy(), these functions will create new object with other reference. If you know more functions to do that, please tell me, thanks!
For Arrays with objects you can change the use JSON.parse and JSON.strinigfy to change the type of the array to an object refrence to a string and then back to a array without having to worry about the original array
var array = [{name:'John', age:34, logs:'[]'}, {name:'David', age:43, logs:'[3]'}];
var array2 = JSON.parse(JSON.stringify(array)); // turn object to function output
array2[0].age++;
alert(JSON.stringify(array));
alert(JSON.stringify(array2));

Using .splice() to create a substitute variable? [duplicate]

I've written the following JavaScript:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
This code declares a variable myArray and sets it to an array value. It then declares a second variable copyOfMyArray and sets it to myArray.
It performs an operation on copyOfMyArray and then alerts both myArray and copyOfMyArray. Somehow, when I perform an operation on copyOfMyArray, it appears that the same operation is performed on myArray.
The code then does the same thing with a number value: It declares a variable myNumber and sets it to a number value. It then declares a second variable copyOfMyNumber and sets it to myNumber. It performs an operation on copyOfMyNumber and then alerts both myNumber and copyOfMyNumber. Here, I get the expected behavior: different values for myNumber and copyOfMyNumber.
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
I'm guessing that for some reason, the array is referred to by reference and the number by value, but why? How can I know what behavior to expect with other objects?
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.
Your comparison with the number example is not correct btw. You assign a new value to copyOfMyNumber. If you assign a new value to copyOfMyArray it will not change myArray either.
You can create a copy of an array using slice [docs]:
var copyOfMyArray = myArray.slice(0);
But note that this only returns a shallow copy, i.e. objects inside the array will not be cloned.
Well, the only possible answer — and the correct one — is that you're not actually copying the array. When you write
var copyOfArray = array;
you're assigning a reference to the same array into another variable. They're both pointing at the same object, in other words.
So everyone here has done a great job of explaining why this is happening - I just wanted to drop a line and let you know how I was able to fix this - pretty easily:
thingArray = ['first_thing', 'second_thing', 'third_thing']
function removeFirstThingAndPreserveArray(){
var copyOfThingArray = [...thingArray]
copyOfThingArray.shift();
return copyOfThingArray;
}
This is using the ... spread syntax.
Spread Syntax Source
EDIT: As to the why of this, and to answer your question:
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
The answer is that in JavaScript, arrays and objects are mutable, while strings and numbers and other primitives are immutable. When we do an assignment like:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray is really just a reference to myArray, not an actual copy.
I would recommend this article, What are immutable and mutable data structures?, to dig deeper into the subject.
MDN Glossary: Mutable
Cloning objects -
A loop / array.push produces a similar result to array.slice(0) or array.clone(). Values are all passed by reference, but since most primitive data types are immutable, subsequent operations produce the desired result - a 'clone'. This is not true of objects and arrays, of course, which allow for modification of the original reference (they are mutable types).
Take the following example:
const originalArray = [1, 'a', false, {foor: 'bar'}]
const newArray = [];
originalArray.forEach((v, i) => {
newArray.push(originalArray[i]);
});
newArray[0] = newArray[0] + 1;
newArray[1] = 'b';
newArray[2] = true;
newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
The operations run on the newArray indices all produce the desired result, except the final (object), which, because it is copied by reference, will mutate the originalArray[3] as well.
https://jsfiddle.net/7ajz2m6w/
Note that array.slice(0) and array.clone() suffers from this same limitation.
One way to solve this is by effectively cloning the object during the push sequence:
originalArray.forEach((v, i) => {
const val = (typeof v === 'object') ? Object.assign({}, v) : v;
newArray.push(val);
});
https://jsfiddle.net/e5hmnjp0/
cheers
The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));
console.log(clonedArray);
// [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy
In JS, operator "=" copy the pointer to the memory area of the array.
If you want to copy an array into another you have to use the Clone function.
For integers is different because they are a primitive type.
S.
Create a filter of the original array in the arrayCopy. So that changes to the new array won't affect original array.
var myArray = ['a', 'b', 'c'];
var arrayCopy = myArray.filter(function(f){return f;})
arrayCopy.splice(0, 1);
alert(myArray); // alerts ['a','b','c']
alert(arrayCopy); // alerts ['b','c']
Hope it helps.
Everything is copied by reference except primitive data types (strings and numbers IIRC).
You don't have any copies.
You have multiple variables holding the same array.
Similarly, you have multiple variables holding the same number.
When you write copyOfMyNumber = ..., you're putting a new number into the variable.
That's like writing copyOfMyArray = ....
When you write copyOfMyArray.splice, you're modifying the original array.
That isn't possible with numbers because numbers are immutable and cannot be modified,
You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.
function CopyAnArray (ari1) {
var mxx4 = [];
for (var i=0;i<ari1.length;i++) {
var nads2 = [];
for (var j=0;j<ari1[0].length;j++) {
nads2.push(ari1[i][j]);
}
mxx4.push(nads2);
}
return mxx4;
}
An array, or an object in javascript always holds the same reference unless you clone or copy. Here is an exmaple:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference
var obj = {
"name": "a"
}
var arr = [];
//we push the same object
arr.push(obj);
arr.push(obj);
//if we change the value for one object
arr[0].name = "b";
//the other object also changes
alert(arr[1].name);
For object clone, we can use .clone() in jquery and angular.copy(), these functions will create new object with other reference. If you know more functions to do that, please tell me, thanks!
For Arrays with objects you can change the use JSON.parse and JSON.strinigfy to change the type of the array to an object refrence to a string and then back to a array without having to worry about the original array
var array = [{name:'John', age:34, logs:'[]'}, {name:'David', age:43, logs:'[3]'}];
var array2 = JSON.parse(JSON.stringify(array)); // turn object to function output
array2[0].age++;
alert(JSON.stringify(array));
alert(JSON.stringify(array2));

useState array only updating on checkbox checked === true [duplicate]

I've written the following JavaScript:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
This code declares a variable myArray and sets it to an array value. It then declares a second variable copyOfMyArray and sets it to myArray.
It performs an operation on copyOfMyArray and then alerts both myArray and copyOfMyArray. Somehow, when I perform an operation on copyOfMyArray, it appears that the same operation is performed on myArray.
The code then does the same thing with a number value: It declares a variable myNumber and sets it to a number value. It then declares a second variable copyOfMyNumber and sets it to myNumber. It performs an operation on copyOfMyNumber and then alerts both myNumber and copyOfMyNumber. Here, I get the expected behavior: different values for myNumber and copyOfMyNumber.
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
I'm guessing that for some reason, the array is referred to by reference and the number by value, but why? How can I know what behavior to expect with other objects?
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.
Your comparison with the number example is not correct btw. You assign a new value to copyOfMyNumber. If you assign a new value to copyOfMyArray it will not change myArray either.
You can create a copy of an array using slice [docs]:
var copyOfMyArray = myArray.slice(0);
But note that this only returns a shallow copy, i.e. objects inside the array will not be cloned.
Well, the only possible answer — and the correct one — is that you're not actually copying the array. When you write
var copyOfArray = array;
you're assigning a reference to the same array into another variable. They're both pointing at the same object, in other words.
So everyone here has done a great job of explaining why this is happening - I just wanted to drop a line and let you know how I was able to fix this - pretty easily:
thingArray = ['first_thing', 'second_thing', 'third_thing']
function removeFirstThingAndPreserveArray(){
var copyOfThingArray = [...thingArray]
copyOfThingArray.shift();
return copyOfThingArray;
}
This is using the ... spread syntax.
Spread Syntax Source
EDIT: As to the why of this, and to answer your question:
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
The answer is that in JavaScript, arrays and objects are mutable, while strings and numbers and other primitives are immutable. When we do an assignment like:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray is really just a reference to myArray, not an actual copy.
I would recommend this article, What are immutable and mutable data structures?, to dig deeper into the subject.
MDN Glossary: Mutable
Cloning objects -
A loop / array.push produces a similar result to array.slice(0) or array.clone(). Values are all passed by reference, but since most primitive data types are immutable, subsequent operations produce the desired result - a 'clone'. This is not true of objects and arrays, of course, which allow for modification of the original reference (they are mutable types).
Take the following example:
const originalArray = [1, 'a', false, {foor: 'bar'}]
const newArray = [];
originalArray.forEach((v, i) => {
newArray.push(originalArray[i]);
});
newArray[0] = newArray[0] + 1;
newArray[1] = 'b';
newArray[2] = true;
newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
The operations run on the newArray indices all produce the desired result, except the final (object), which, because it is copied by reference, will mutate the originalArray[3] as well.
https://jsfiddle.net/7ajz2m6w/
Note that array.slice(0) and array.clone() suffers from this same limitation.
One way to solve this is by effectively cloning the object during the push sequence:
originalArray.forEach((v, i) => {
const val = (typeof v === 'object') ? Object.assign({}, v) : v;
newArray.push(val);
});
https://jsfiddle.net/e5hmnjp0/
cheers
The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));
console.log(clonedArray);
// [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy
In JS, operator "=" copy the pointer to the memory area of the array.
If you want to copy an array into another you have to use the Clone function.
For integers is different because they are a primitive type.
S.
Create a filter of the original array in the arrayCopy. So that changes to the new array won't affect original array.
var myArray = ['a', 'b', 'c'];
var arrayCopy = myArray.filter(function(f){return f;})
arrayCopy.splice(0, 1);
alert(myArray); // alerts ['a','b','c']
alert(arrayCopy); // alerts ['b','c']
Hope it helps.
Everything is copied by reference except primitive data types (strings and numbers IIRC).
You don't have any copies.
You have multiple variables holding the same array.
Similarly, you have multiple variables holding the same number.
When you write copyOfMyNumber = ..., you're putting a new number into the variable.
That's like writing copyOfMyArray = ....
When you write copyOfMyArray.splice, you're modifying the original array.
That isn't possible with numbers because numbers are immutable and cannot be modified,
You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.
function CopyAnArray (ari1) {
var mxx4 = [];
for (var i=0;i<ari1.length;i++) {
var nads2 = [];
for (var j=0;j<ari1[0].length;j++) {
nads2.push(ari1[i][j]);
}
mxx4.push(nads2);
}
return mxx4;
}
An array, or an object in javascript always holds the same reference unless you clone or copy. Here is an exmaple:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference
var obj = {
"name": "a"
}
var arr = [];
//we push the same object
arr.push(obj);
arr.push(obj);
//if we change the value for one object
arr[0].name = "b";
//the other object also changes
alert(arr[1].name);
For object clone, we can use .clone() in jquery and angular.copy(), these functions will create new object with other reference. If you know more functions to do that, please tell me, thanks!
For Arrays with objects you can change the use JSON.parse and JSON.strinigfy to change the type of the array to an object refrence to a string and then back to a array without having to worry about the original array
var array = [{name:'John', age:34, logs:'[]'}, {name:'David', age:43, logs:'[3]'}];
var array2 = JSON.parse(JSON.stringify(array)); // turn object to function output
array2[0].age++;
alert(JSON.stringify(array));
alert(JSON.stringify(array2));

Can't compare array length at two points in time when push() updates the array? [duplicate]

I've written the following JavaScript:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
This code declares a variable myArray and sets it to an array value. It then declares a second variable copyOfMyArray and sets it to myArray.
It performs an operation on copyOfMyArray and then alerts both myArray and copyOfMyArray. Somehow, when I perform an operation on copyOfMyArray, it appears that the same operation is performed on myArray.
The code then does the same thing with a number value: It declares a variable myNumber and sets it to a number value. It then declares a second variable copyOfMyNumber and sets it to myNumber. It performs an operation on copyOfMyNumber and then alerts both myNumber and copyOfMyNumber. Here, I get the expected behavior: different values for myNumber and copyOfMyNumber.
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
I'm guessing that for some reason, the array is referred to by reference and the number by value, but why? How can I know what behavior to expect with other objects?
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.
Your comparison with the number example is not correct btw. You assign a new value to copyOfMyNumber. If you assign a new value to copyOfMyArray it will not change myArray either.
You can create a copy of an array using slice [docs]:
var copyOfMyArray = myArray.slice(0);
But note that this only returns a shallow copy, i.e. objects inside the array will not be cloned.
Well, the only possible answer — and the correct one — is that you're not actually copying the array. When you write
var copyOfArray = array;
you're assigning a reference to the same array into another variable. They're both pointing at the same object, in other words.
So everyone here has done a great job of explaining why this is happening - I just wanted to drop a line and let you know how I was able to fix this - pretty easily:
thingArray = ['first_thing', 'second_thing', 'third_thing']
function removeFirstThingAndPreserveArray(){
var copyOfThingArray = [...thingArray]
copyOfThingArray.shift();
return copyOfThingArray;
}
This is using the ... spread syntax.
Spread Syntax Source
EDIT: As to the why of this, and to answer your question:
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
The answer is that in JavaScript, arrays and objects are mutable, while strings and numbers and other primitives are immutable. When we do an assignment like:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray is really just a reference to myArray, not an actual copy.
I would recommend this article, What are immutable and mutable data structures?, to dig deeper into the subject.
MDN Glossary: Mutable
Cloning objects -
A loop / array.push produces a similar result to array.slice(0) or array.clone(). Values are all passed by reference, but since most primitive data types are immutable, subsequent operations produce the desired result - a 'clone'. This is not true of objects and arrays, of course, which allow for modification of the original reference (they are mutable types).
Take the following example:
const originalArray = [1, 'a', false, {foor: 'bar'}]
const newArray = [];
originalArray.forEach((v, i) => {
newArray.push(originalArray[i]);
});
newArray[0] = newArray[0] + 1;
newArray[1] = 'b';
newArray[2] = true;
newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
The operations run on the newArray indices all produce the desired result, except the final (object), which, because it is copied by reference, will mutate the originalArray[3] as well.
https://jsfiddle.net/7ajz2m6w/
Note that array.slice(0) and array.clone() suffers from this same limitation.
One way to solve this is by effectively cloning the object during the push sequence:
originalArray.forEach((v, i) => {
const val = (typeof v === 'object') ? Object.assign({}, v) : v;
newArray.push(val);
});
https://jsfiddle.net/e5hmnjp0/
cheers
The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));
console.log(clonedArray);
// [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy
In JS, operator "=" copy the pointer to the memory area of the array.
If you want to copy an array into another you have to use the Clone function.
For integers is different because they are a primitive type.
S.
Create a filter of the original array in the arrayCopy. So that changes to the new array won't affect original array.
var myArray = ['a', 'b', 'c'];
var arrayCopy = myArray.filter(function(f){return f;})
arrayCopy.splice(0, 1);
alert(myArray); // alerts ['a','b','c']
alert(arrayCopy); // alerts ['b','c']
Hope it helps.
Everything is copied by reference except primitive data types (strings and numbers IIRC).
You don't have any copies.
You have multiple variables holding the same array.
Similarly, you have multiple variables holding the same number.
When you write copyOfMyNumber = ..., you're putting a new number into the variable.
That's like writing copyOfMyArray = ....
When you write copyOfMyArray.splice, you're modifying the original array.
That isn't possible with numbers because numbers are immutable and cannot be modified,
You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.
function CopyAnArray (ari1) {
var mxx4 = [];
for (var i=0;i<ari1.length;i++) {
var nads2 = [];
for (var j=0;j<ari1[0].length;j++) {
nads2.push(ari1[i][j]);
}
mxx4.push(nads2);
}
return mxx4;
}
An array, or an object in javascript always holds the same reference unless you clone or copy. Here is an exmaple:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference
var obj = {
"name": "a"
}
var arr = [];
//we push the same object
arr.push(obj);
arr.push(obj);
//if we change the value for one object
arr[0].name = "b";
//the other object also changes
alert(arr[1].name);
For object clone, we can use .clone() in jquery and angular.copy(), these functions will create new object with other reference. If you know more functions to do that, please tell me, thanks!
For Arrays with objects you can change the use JSON.parse and JSON.strinigfy to change the type of the array to an object refrence to a string and then back to a array without having to worry about the original array
var array = [{name:'John', age:34, logs:'[]'}, {name:'David', age:43, logs:'[3]'}];
var array2 = JSON.parse(JSON.stringify(array)); // turn object to function output
array2[0].age++;
alert(JSON.stringify(array));
alert(JSON.stringify(array2));

Why does changing an Array in JavaScript affect copies of the array?

I've written the following JavaScript:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // alerts ['b','c']
alert(copyOfMyArray); // alerts ['b','c']
var myNumber = 5;
var copyOfMyNumber = myNumber;
copyOfMyNumber = copyOfMyNumber - 1;
alert(myNumber); // alerts 5
alert(copyOfMyNumber); // alerts 4
This code declares a variable myArray and sets it to an array value. It then declares a second variable copyOfMyArray and sets it to myArray.
It performs an operation on copyOfMyArray and then alerts both myArray and copyOfMyArray. Somehow, when I perform an operation on copyOfMyArray, it appears that the same operation is performed on myArray.
The code then does the same thing with a number value: It declares a variable myNumber and sets it to a number value. It then declares a second variable copyOfMyNumber and sets it to myNumber. It performs an operation on copyOfMyNumber and then alerts both myNumber and copyOfMyNumber. Here, I get the expected behavior: different values for myNumber and copyOfMyNumber.
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
I'm guessing that for some reason, the array is referred to by reference and the number by value, but why? How can I know what behavior to expect with other objects?
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.
Your comparison with the number example is not correct btw. You assign a new value to copyOfMyNumber. If you assign a new value to copyOfMyArray it will not change myArray either.
You can create a copy of an array using slice [docs]:
var copyOfMyArray = myArray.slice(0);
But note that this only returns a shallow copy, i.e. objects inside the array will not be cloned.
Well, the only possible answer — and the correct one — is that you're not actually copying the array. When you write
var copyOfArray = array;
you're assigning a reference to the same array into another variable. They're both pointing at the same object, in other words.
So everyone here has done a great job of explaining why this is happening - I just wanted to drop a line and let you know how I was able to fix this - pretty easily:
thingArray = ['first_thing', 'second_thing', 'third_thing']
function removeFirstThingAndPreserveArray(){
var copyOfThingArray = [...thingArray]
copyOfThingArray.shift();
return copyOfThingArray;
}
This is using the ... spread syntax.
Spread Syntax Source
EDIT: As to the why of this, and to answer your question:
What is the difference between an array and a number in JavaScript that it seems changing an array changes the value of a copy of the array, where as changing a number does not change the value of a copy of the number?
The answer is that in JavaScript, arrays and objects are mutable, while strings and numbers and other primitives are immutable. When we do an assignment like:
var myArray = ['a', 'b', 'c'];
var copyOfMyArray = myArray;
copyOfMyArray is really just a reference to myArray, not an actual copy.
I would recommend this article, What are immutable and mutable data structures?, to dig deeper into the subject.
MDN Glossary: Mutable
Cloning objects -
A loop / array.push produces a similar result to array.slice(0) or array.clone(). Values are all passed by reference, but since most primitive data types are immutable, subsequent operations produce the desired result - a 'clone'. This is not true of objects and arrays, of course, which allow for modification of the original reference (they are mutable types).
Take the following example:
const originalArray = [1, 'a', false, {foor: 'bar'}]
const newArray = [];
originalArray.forEach((v, i) => {
newArray.push(originalArray[i]);
});
newArray[0] = newArray[0] + 1;
newArray[1] = 'b';
newArray[2] = true;
newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
The operations run on the newArray indices all produce the desired result, except the final (object), which, because it is copied by reference, will mutate the originalArray[3] as well.
https://jsfiddle.net/7ajz2m6w/
Note that array.slice(0) and array.clone() suffers from this same limitation.
One way to solve this is by effectively cloning the object during the push sequence:
originalArray.forEach((v, i) => {
const val = (typeof v === 'object') ? Object.assign({}, v) : v;
newArray.push(val);
});
https://jsfiddle.net/e5hmnjp0/
cheers
The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..
var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));
console.log(clonedArray);
// [{name: 'foo', id: 121}, {name: 'zoo', id: 321}] // shallow copy
In JS, operator "=" copy the pointer to the memory area of the array.
If you want to copy an array into another you have to use the Clone function.
For integers is different because they are a primitive type.
S.
Create a filter of the original array in the arrayCopy. So that changes to the new array won't affect original array.
var myArray = ['a', 'b', 'c'];
var arrayCopy = myArray.filter(function(f){return f;})
arrayCopy.splice(0, 1);
alert(myArray); // alerts ['a','b','c']
alert(arrayCopy); // alerts ['b','c']
Hope it helps.
Everything is copied by reference except primitive data types (strings and numbers IIRC).
You don't have any copies.
You have multiple variables holding the same array.
Similarly, you have multiple variables holding the same number.
When you write copyOfMyNumber = ..., you're putting a new number into the variable.
That's like writing copyOfMyArray = ....
When you write copyOfMyArray.splice, you're modifying the original array.
That isn't possible with numbers because numbers are immutable and cannot be modified,
You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.
function CopyAnArray (ari1) {
var mxx4 = [];
for (var i=0;i<ari1.length;i++) {
var nads2 = [];
for (var j=0;j<ari1[0].length;j++) {
nads2.push(ari1[i][j]);
}
mxx4.push(nads2);
}
return mxx4;
}
An array, or an object in javascript always holds the same reference unless you clone or copy. Here is an exmaple:
http://plnkr.co/edit/Bqvsiddke27w9nLwYhcl?p=preview
// for showing that objects in javascript shares the same reference
var obj = {
"name": "a"
}
var arr = [];
//we push the same object
arr.push(obj);
arr.push(obj);
//if we change the value for one object
arr[0].name = "b";
//the other object also changes
alert(arr[1].name);
For object clone, we can use .clone() in jquery and angular.copy(), these functions will create new object with other reference. If you know more functions to do that, please tell me, thanks!
For Arrays with objects you can change the use JSON.parse and JSON.strinigfy to change the type of the array to an object refrence to a string and then back to a array without having to worry about the original array
var array = [{name:'John', age:34, logs:'[]'}, {name:'David', age:43, logs:'[3]'}];
var array2 = JSON.parse(JSON.stringify(array)); // turn object to function output
array2[0].age++;
alert(JSON.stringify(array));
alert(JSON.stringify(array2));

Categories