javascript対象の浅いコピー、深いコピーとObject.assign方法は簡単に分析します.
3709 ワード
オブジェクトの浅いコピー:
浅いコピーは対象が一つのメモリアドレスを共有し、対象の変化は相互に影響します.例えば、よくある割当値の参照は、浅いコピーです.
深くコピーすることは、オブジェクトを新しいメモリに置くことです.二つのオブジェクトの変化は相互に影響しません.
Object.assign()
MDNでは、Object.assign()を紹介し、'Object.assign()方法は、列挙可能な属性のすべての値を1つ以上のソースオブジェクトから対象オブジェクトにコピーするために使用される.ターゲットに戻ります.
深度コピーの実現
多くの第三者倉庫が対象の深度コピーを実現しました.例えば、よくあるJqueryとundersscoreは未来のlodashを比較して、ソースコードを実現してまだ詳しく分析していません.分析してから補充します.しかし、これらのライブラリを導入していない場合は、深くコピーするための簡単な方法があります.
JSON.parse()とJSON.strigify()
JSON.parse()とJSON.strigify()は、深くコピーした無脳に対して実現されたものです.例を見てください.
後でまた深くコピーして考えを実現します....
配列の深度コピーと浅いコピー
最後に一点配列を補足する深度コピーと浅いコピーは、オブジェクトと同じ配列の浅いコピーもその中の一つを変えて相互に影響します. concat slice es 6のARray.from
浅いコピーは対象が一つのメモリアドレスを共有し、対象の変化は相互に影響します.例えば、よくある割当値の参照は、浅いコピーです.
let srcObj = {'name': 'lilei', 'age': '20'};
let copyObj = srcObj;
copyObj.age = '22';
console.log('srcObj', srcObj); // srcObj { name: 'lilei', age: '22' }
console.log('copyObj', copyObj); // copyObj { name: 'lilei', age: '22' }
オブジェクトの深度コピー:深くコピーすることは、オブジェクトを新しいメモリに置くことです.二つのオブジェクトの変化は相互に影響しません.
Object.assign()
MDNでは、Object.assign()を紹介し、'Object.assign()方法は、列挙可能な属性のすべての値を1つ以上のソースオブジェクトから対象オブジェクトにコピーするために使用される.ターゲットに戻ります.
let srcObj = {'name': 'lilei', 'age': '20'};
let copyObj2 = Object.assign({}, srcObj, {'age': '21'});
copyObj2.age = '23';
console.log('srcObj', srcObj); //{ name: 'lilei', age: '22' }
深くコピーしたように見えますが、ここではlet copyObj2 = Object.assign({}, srcObj, {'age': '21'});
号にsrccebjを新しい空のオブジェクトにあげました.同じターゲットが{}です.もう一度テストしてみます.srcObj = {'name': ' ', grade: {'chi': '50', 'eng': '50'} };
copyObj2 = Object.assign({}, srcObj);
copyObj2.name = ' ';
copyObj2.grade.chi = '60';
console.log(' objec srcObj', srcObj); // { name: ' ', grade: { chi: '60', eng: '50' } }
例からわかるように、複製対象を変えるnameとgrade.chiは、ソースオブジェクトのnameは変化していないが、grade.ciは変更されている.したがって、Object.assign()コピーは属性値だけであることが分かります.ソースオブジェクトの属性値がオブジェクトへの参照であれば、その参照値だけコピーします.つまり、Object.assign()にとって、オブジェクトの属性値がシンプルなタイプであれば、Object.assign({},srcObj);
を介して得られた新しいオブジェクトは“深コピー”である.属性値がオブジェクトまたは他の参照タイプの場合は、このオブジェクトに対しては、実際には浅いコピーです.これはObject.assignの特に注意すべきところです.つまり、Object.assign({}, src1, src2);
は、scr 1とsrc 2との間の同じ属性を直接カバーしており、属性値がオブジェクトである場合、オブジェクト間の属性はマージされない.深度コピーの実現
多くの第三者倉庫が対象の深度コピーを実現しました.例えば、よくあるJqueryとundersscoreは未来のlodashを比較して、ソースコードを実現してまだ詳しく分析していません.分析してから補充します.しかし、これらのライブラリを導入していない場合は、深くコピーするための簡単な方法があります.
JSON.parse()とJSON.strigify()
JSON.parse()とJSON.strigify()は、深くコピーした無脳に対して実現されたものです.例を見てください.
srcObj = {'name': ' ', grade: {'chi': '50', 'eng': '50'} };
// copyObj2 = Object.assign({}, srcObj);
copyObj2 = JSON.parse(JSON.stringify(srcObj));
copyObj2.name = ' ';
copyObj2.grade.chi = '60';
console.log('JSON srcObj', srcObj); // { name: ' ', grade: { chi: '50', eng: '50' } }
copyObj 2の変更は元のオブジェクトを変えず、基本的に深いコピーを実現していることが見られます.しかし、JSON.parse()とJSON.strigify()を使うと問題があります.JSON.parse()とJSON.strigify()が正確に処理できる対象はNumber、String、Arayなどがjsonによって表し得るデータ構造だけであり、このような関数がJsonによって表されないタイプは正確に処理されなくなります.たとえばsrcObj = {'name': ' ', grade: {'chi': '50', 'eng': '50'},
'hello': function() {console.log('hello')}};
// copyObj2 = Object.assign({}, srcObj);
copyObj2 = JSON.parse(JSON.stringify(srcObj));
copyObj2.name = ' ';
copyObj2.grade.chi = '60';
console.log('JSON srcObj', copyObj2); //{ name: ' ', grade: { chi: '60', eng: '50' } }
変換した後、機能が無くなりましたので、JSON.parse()とJSON.strigify()は慎重に使う必要があります.後でまた深くコピーして考えを実現します....
配列の深度コピーと浅いコピー
最後に一点配列を補足する深度コピーと浅いコピーは、オブジェクトと同じ配列の浅いコピーもその中の一つを変えて相互に影響します.
let srcArr = [1, 2, 3];
let copyArr = srcArr;
copyArr[0] = '0';
console.log('srcArr', srcArr); // ['0', 2, 3]
しかし、配列の深度コピー方法は比較的簡単であり、配列方法においては、元の配列を変える方法として理解され得る.