Почему вычисляемые данные изменяются при присвоении данных переменной?

Я только что заметил странное поведение Vue.js при использовании вычисляемых свойств. Может быть, я что-то упускаю, и это правильное поведение, но для меня это не имеет смысла. Если вы посмотрите на следующий код, вы увидите, что внутри вычисляемого свойства я создал новую переменную и назначил массив, определенный в «данных». Затем я ввел некоторые новые данные во вновь созданную переменную. Теперь изменился и массив в «data»! Почему это?

new Vue({
  el: "#app",
  data: {
    items: ['foo', 'bar']
  },
  computed: {
    someComputed() {
      let some = this.items
      some.push('foobar')
      return some
    }
  }
})
<div id="app">
  {{ someComputed }} – {{ items }}
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>


person Chris    schedule 25.12.2018    source источник
comment
Побочные эффекты в вычислениях — плохая практика.   -  person Roy J    schedule 25.12.2018
comment
При использовании нет побочных эффектов this.items.slice() Действительно любопытно, почему мой вопрос был отклонен...   -  person Chris    schedule 26.12.2018
comment
Я не голосовал, я просто прокомментировал.   -  person Roy J    schedule 26.12.2018


Ответы (2)


Это связано с тем, что «Вызов по ссылке» вы просто ссылаетесь на массив из данных. Это похоже на указатель, some и this.items указывают на один и тот же объект.
Если вам нужна копия this.items, вам нужно позвонить.

let some = this.items.slice()

Таким образом, вы получаете совершенно новый объект, а не просто новую «ссылку».
Обычно JS использует «Вызов по значению», но для объектов и массивов значение является ссылкой.
Изменить:
Иметь взгляните на: Javascript передает массивы функциям значение, оставляя исходный массив без изменений

person mava    schedule 25.12.2018

Вы должны сделать копию этого с помощью this.items.slice(0)

new Vue({
  el: "#app",
  data: {
    items: ['foo', 'bar']
  },
  computed: {
    someComputed() {
      let some = this.items.slice(0)
      some.push('foobar')
      return some
    }
  }
})
<div id="app">
  {{ someComputed }} – {{ items }}
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

person Maxim    schedule 25.12.2018