So I have this code in vue:
export default {
name: 'Test',
data() {
return {
test1: ['1', '2', '3'],
test2: [{
name: 'Hello'
}, {
name: 'Number two'
}, {
name: 'What ever'
}],
};
},
created() {
const first = [...this.test1];
first.forEach((elm, index) => first[index] = 'New');
console.log('first: ', first);
console.log('test1 in data', this.test1);
const second = [...this.test2];
second.forEach(elm => elm.name = 'New');
console.log('second: ', second);
console.log('test2 in data', this.test2);
},
}
After setting the value of each item of the array 'first' (that should be a copy without reference to the data 'test1' array) each item is equal to 'new'. The value of this.test1 doesn't change.
I did the same with test2. Copied and changed the value of each item to 'New'. But now the value of the data array 'test2' also has 'New' in every item.
I have no clue why this is like that. Any ideas?
So I have this code in vue:
export default {
name: 'Test',
data() {
return {
test1: ['1', '2', '3'],
test2: [{
name: 'Hello'
}, {
name: 'Number two'
}, {
name: 'What ever'
}],
};
},
created() {
const first = [...this.test1];
first.forEach((elm, index) => first[index] = 'New');
console.log('first: ', first);
console.log('test1 in data', this.test1);
const second = [...this.test2];
second.forEach(elm => elm.name = 'New');
console.log('second: ', second);
console.log('test2 in data', this.test2);
},
}
After setting the value of each item of the array 'first' (that should be a copy without reference to the data 'test1' array) each item is equal to 'new'. The value of this.test1 doesn't change.
I did the same with test2. Copied and changed the value of each item to 'New'. But now the value of the data array 'test2' also has 'New' in every item.
I have no clue why this is like that. Any ideas?
Share Improve this question asked Feb 21, 2019 at 7:58 MichaMicha 2571 gold badge3 silver badges11 bronze badges3 Answers
Reset to default 12Spread syntax creates a shallow copy. If your array has primitive types like numbers or strings, it won't update the original array. That's the case with test1
. In the second case, only a new array is created. If you push
or pop
from the array, original array won't be updated. But, the objects are still pointing to their same place in memory. Updating them will update original array's objects as well.
You can use the spread syntax on the individual object to create a copy of the objects:
const second = this.test2.map(o => ({...o}))
You can also use JSON.parse
and JSON.stringify
. But, if the objects have any function properties, they'll be removed.
const second = JSON.parse(JSON.stringify(this.test2))
The reason it is like that is because you are having an array of Vue data values
. So even though you are cloning the Array, you are also copying over each values 'getters' and 'setters' which have a reference to the original array. In order to remove the getters and setters you should do what d-h-e has suggested.
You could also do this.
const second = this.test2.map(() => { name: 'New' } );
console.log('second: ', second);
console.log('test2 in data', this.test2);
Try it with:
const second = JSON.parse(JSON.stringify(this.test2));
The copy method with spreadoperator or Array.from works only with simple arrays. For deep copy use the method with JSON.parse and JSON.stringify.