vue Object.assign导致源对象被改变

其中settings assest文件夹中的json, 经过log方法后源文件被改变了。

import vuedraggable from 'vuedraggable'
import RenderString from './RenderString'
import { mapState, mapMutations } from 'vuex'
import settings from '@/assets/settings.json'

export default {
  name: 'ShowArea',
  components: {
    vuedraggable,
    RenderString
  },
  data () {
    return {
      list: [],
      active: -1
    }
  },
  computed: {
    ...mapState({
      attrs: state => state.attrs
    })
  },
  methods: {
    selected (item, index) {
      this.active = index
    },
    log (t) {
      for (let i in t) {
        this.active = t[i].newIndex
        const item = this.list[this.active]
        if (i === 'added') {
          const d = window.Object.assign({}, settings[item.name], { name: item.name })
          console.log(settings) // 这个json文件内容被改变了
          const arr = this.attrs
          arr.splice(this.active, 1, d)
          this.setAttrs(arr)
        }
      }
    },
    ...mapMutations({
      setAttrs: 'changeAttrs',
      setActiveAttrs: 'setActiveAttrs'
    })
  },
  watch: {
    active () {
      this.setActiveAttrs(this.active)
    }
  }
}
</script>
阅读 6.3k
2 个回答

var a = 1;
var b = 2;
a = b;
b = 3;
a = ?

a的变量值将不会改变,因为a是基本类型

var a = {}
a.c = 1; a.d =2; a.d = 3
var b= a;
b.g = 8
a?

因为ab引用类型,赋值不是简单的赋值数据,而是赋值内存地址,因为b和a的地址指向一个地方,所以b改变了,a也会变.

使用JSON.stringify和JSON.parse可以解决问题

const d = window.Object.assign({}, this.clone(settings[item.name]), { name: item.name })

给vue搞个clone方法

Vue.prototype.clone = function (o) {
  if (!o) return ''
  return JSON.parse(JSON.stringify(o))
}
这样完全可以避免发生引用数据被更改的现象,但是在此代码中,确实不是object.assign引起的,object.assign只会改变目标对象,源对象不会改变

使用JSON.parse(JSON.stringify)方法转换为基本类型再转换成引用类型,确实可以改变原引用的内存地址达到复制克隆的效果, 然而源对象何时改变的,无法得知。

应该有其他地方修改了 settings,不是这句代码引起的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题