最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue changes array in data after making a copy of it - Stack Overflow

programmeradmin8浏览0评论

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 badges
Add a comment  | 

3 Answers 3

Reset to default 12

Spread 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.

发布评论

评论列表(0)

  1. 暂无评论