当封装在 VueJS 计算属性中时,JavaScript 对象的深度复制不起作用

问题描述

我在 Vue 实例中有一个 JavaScript 对象,该对象通过计算属性被深度复制到另一个 JavaScript 对象中。然而由于某种原因,它浅拷贝有问题的对象而不是深拷贝,即使使用了 JSON.parse(JSON.stringify())

<div id="app">
  <v-app id="inspire">
    <v-row>
      <v-col cols="6">
        <v-text-field 
          v-model="formDialog.inputs.deFinition.val" 
          placeholder="DeFinition from FormDialog"></v-text-field>  
      </v-col>  
      <v-col cols="6">
        <v-text-field 
          v-model="initFields.deFinition" 
          placeholder="DeFinition from Init Fields"></v-text-field>
      </v-col>
    </v-row>
    
    <v-row>
      <v-col cols="6">
        <v-text-field 
          v-model="formDialog.inputs.synonym.val" 
          placeholder="Synonym from FormDialog"></v-text-field>
      </v-col>  
      <v-col cols="6">
        <v-text-field 
          v-model="initFields.synonym" 
          placeholder="Synonym from Init Fields"></v-text-field>
      </v-col>
    </v-row>
   
  </v-app>
</div>

我正在尝试在计算属性中使用以下循环深度复制 formDialog.inputs 的值:

new Vue({
  el: '#app',vuetify: new Vuetify(),data () {
    return {
      formDialog: {
                    inputs: {
                        deFinition: {
                            val: '',save: true,add: true,icon: 'mdi-file-word',placeholder: 'Word DeFinition'
                        },synonym: {
                            val: '',placeholder: 'Synonyms'
                        }
                    }
                }
    }
  },computed: {
    initFields: function() {
      let obj = {};
      if(typeof this.formDialog.inputs != 'undefined') {
        for(let key of Object.keys(this.formDialog.inputs)) {
          if(typeof this.formDialog.inputs[key].val != 'undefined') {
            //obj[key] = JSON.parse(JSON.stringify(this.formDialog.inputs[key]));
            obj[key] = this.formDialog.inputs[key].val;
          }
        }
      }

      return JSON.parse(JSON.stringify(obj));
      //return obj;
    }  
  }
})

然而,obj 对象保留了 this.formDialog.inputs 对象的浅拷贝,而我希望它能够对其进行深拷贝。为什么即使我使用 JSON.parse(JSON.stringify(obj)) 也不创建对象的深层副本?

问题演示: https://codepen.io/deftonez4me/pen/qBapYgP

解决方法

这是您的代码的一个略有删节的版本,我相信它可以达到我们的目的:

const formDialog = {
    inputs: {
        id: {
            val: '',save: true,},word_data: [],definition: {
            val: '',add: true,icon: 'mdi-file-word',placeholder: 'Word Definition'
        },synonym: {
            val: '',placeholder: 'Synonyms'
        }
    }
}

let obj = {};
for(let key of Object.keys(formDialog.inputs)) {
    if(typeof formDialog.inputs[key].val !== 'undefined') {
        //why is this line making a shallow copy and not a deep copy?
        obj[key] = JSON.parse(JSON.stringify(formDialog.inputs[key]));
    }
}

obj.id.val = 'zunit';

console.log(obj);

console.log(formDialog)

请注意,在将 val 送入 JSON.stringify 之前,我已对您的循环进行了修正。你提到了

obj 对象中的元素仍然保留对 this.formDialog.inputs 元素的引用。当我修改 this.formDialog.inputs 时,它也会修改 obj 元素

但恐怕这不是真的,正如您通过更改克隆对象的 obj.id.val 所看到的那样,原始对象不受影响。

因此,除此之外,您的代码运行良好。也许您的特定环境会产生问题,因为您似乎在课堂上这样做。

,

你应该试试这个:

    if (this.formDialog.hasOwnProperty('inputs')) {
        obj[key] = JSON.parse(JSON.stringify(this.formDialog.inputs));
    }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...