Rumah  >  Soal Jawab  >  teks badan

Mengubah suai salinan objek JavaScript menyebabkan perubahan pada objek asal

<p>Saya sedang menyalin <kod>objA</kod> <pre class="brush:php;toolbar:false;">const objA = { prop: 1 }, const objB = objA; objB.prop = 2; console.log(objA.prop); // log 2 bukannya 1</pre> <p>Array juga mempunyai masalah yang sama</p> <pre class="brush:php;toolbar:false;">const arrA = [1, 2, 3], const arrB = arrA; arrB.push(4); console.log(arrA.length); // `arrA` mempunyai 4 elemen dan bukannya 3.</pre> <p><br /></p>
P粉765684602P粉765684602419 hari yang lalu467

membalas semua(2)saya akan balas

  • P粉394812277

    P粉3948122772023-08-28 17:35:35

    Untuk meringkaskan, hanya untuk menjelaskan, terdapat empat cara untuk menyalin objek JS.

    1. Salinan biasa. Apabila anda menukar sifat objek asal, sifat objek yang disalin juga berubah (dan sebaliknya).
    const a = { x: 0}
    const b = a;
    b.x = 1; // also updates a.x
    
    1. Salinan cetek. Sifat peringkat atas bagi objek asal dan yang disalin akan menjadi unik. Walau bagaimanapun, sifat bersarang akan dikongsi antara kedua-dua objek. Gunakan operator spread ...{}Object.assign().
    const a = { x: 0, y: { z: 0 } };
    const b = {...a}; // or const b = Object.assign({}, a);
    
    b.x = 1; // doesn't update a.x
    b.y.z = 1; // also updates a.y.z
    
    1. Salinan Dalam. Semua sifat adalah unik kepada objek asal dan disalin, malah sifat bersarang. Untuk salinan yang mendalam, sirikan objek kepada JSON dan huraikannya semula ke dalam objek JS.
    const a = { x: 0, y: { z: 0 } };
    const b = JSON.parse(JSON.stringify(a)); 
    
    b.y.z = 1; // doesn't update a.y.z
    
    1. Salinan penuh dalam. Menggunakan teknik di atas, nilai harta tidak sah (seperti fungsi) dalam JSON akan dibuang. Jika anda perlu menyalin dalam dan mengekalkan sifat bersarang yang mengandungi fungsi, anda mungkin mahu melihat perpustakaan utiliti seperti lodash .
    import { cloneDeep } from "lodash"; 
    const a = { x: 0, y: { z: (a, b) => a + b } };
    const b = cloneDeep(a);
    
    console.log(b.y.z(1, 2)); // returns 3
    
    1. Gunakan Object.create()确实创建了一个新对象。这些属性在对象之间共享(更改其中一个也会更改另一个)。与普通副本的区别在于,属性被添加到新对象的原型 __proto__ di bawah. Ini juga boleh digunakan sebagai salinan cetek apabila anda tidak pernah menukar objek asal, tetapi saya mengesyorkan menggunakan salah satu kaedah di atas melainkan anda memerlukan tingkah laku ini secara khusus.

    balas
    0
  • P粉520545753

    P粉5205457532023-08-28 12:57:02

    Jelas sekali anda mempunyai beberapa salah faham tentang perkara yang dilakukan oleh pernyataan var tempMyObj = myObj; itu.

    Dalam JavaScript, objek diluluskan dan diperuntukkan melalui rujukan (lebih tepat, nilai rujukan), jadi tempMyObjmyObj adalah semua rujukan kepada objek yang sama.

    Berikut ialah ilustrasi ringkas untuk membantu anda membayangkan perkara yang sedang berlaku

    // [Object1]<--------- myObj
    
    var tempMyObj = myObj;
    
    // [Object1]<--------- myObj
    //         ^ 
    //         |
    //         ----------- tempMyObj

    Seperti yang anda lihat selepas tugasan, kedua-dua rujukan menghala ke objek yang sama.

    Jika anda perlu mengubah suai satu tetapi tidak yang lain, anda perlu membuat salinan.

    // [Object1]<--------- myObj
    
    const tempMyObj = Object.assign({}, myObj);
    
    // [Object1]<--------- myObj
    // [Object2]<--------- tempMyObj

    Jawapan lama:

    Berikut ialah beberapa cara lain untuk membuat salinan objek

    Memandangkan anda sudah menggunakan jQuery:

    var newObject = jQuery.extend(true, {}, myObj);

    Gunakan JavaScript biasa

    function clone(obj) {
        if (null == obj || "object" != typeof obj) return obj;
        var copy = obj.constructor();
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
        }
        return copy;
    }
    
    var newObject = clone(myObj);

    Lihat di sini dan di sini

    balas
    0
  • Batalbalas