ホームページ >ウェブフロントエンド >フロントエンドQ&A >JavaScriptのディープコピーとシャローコピーの違いは何ですか

JavaScriptのディープコピーとシャローコピーの違いは何ですか

WBOY
WBOYオリジナル
2022-03-10 11:24:206760ブラウズ

JavaScript では、シャロー コピーは元のデータのメモリ アドレスのみをコピーします。これは、同じアドレスを指す 2 つのデータ ポインターに相当します。いずれかのデータ要素が変更されると、もう一方のデータ要素にも影響します。ディープ コピーの 2 つのデータ要素 データは異なるアドレスを指しているため、一方の要素を変更しても、もう一方の要素には影響しません。

JavaScriptのディープコピーとシャローコピーの違いは何ですか

このチュートリアルの動作環境: Windows 10 システム、JavaScript バージョン 1.8.5、Dell G3 コンピューター。

JavaScript におけるディープ コピーとシャロー コピーの違いは何ですか

シャロー コピーとディープ コピーについて調べる前に、まずヒープとスタックの概念を理解しましょう

ヒープとスタックの両方スタック メモリを分割して格納する領域です。スタックは自動的に割り当てられるメモリ領域であり、システムによって自動的に解放されます。ヒープは動的に割り当てられるメモリであり、そのサイズは可変で、自動的には解放されません。

基本データ型と参照データ型 (複合データ型とも呼ばれます) を見てみましょう

1. 基本型: 文字列、数値、ブール値、null、未定義、シンボル (ES6 の新機能) 、一意の値を表します); 基本型の値はメモリ内の固定サイズを占有し、スタック メモリに格納されます。

2. 参照型: オブジェクト、配列、日付、関数など; 参照型の値はオブジェクトであり、ヒープ メモリに格納されます。

深いコピーと浅いコピーの概念

注: 深いコピーと浅いコピーの違いは、配列やオブジェクトなどの複雑なオブジェクトにのみ適用されます。

1. 浅いコピー: 元のデータのメモリ アドレスのみをコピーします。これは、同じアドレスを指す 2 つのデータ ポインターに相当します。いずれかのデータ要素を変更すると、もう一方のデータ要素に影響します。

2. ディープ コピー: 2 つのデータは異なるアドレスを指しており、データ要素が変更されても相互に影響しません。

研究例

1. 浅いコピー

var arr = [0, 1, 2];
var arrB;
 
//把arr赋值给arrB
arrB = arr;
console.log("arr:", arr);
console.log("arrB:", arrB);
console.log("-----------改变arrB中数组元素的值后-----------");
arrB[0] = 5;
console.log("arr:", arr);
console.log("arrB:", arrB);

操作結果: arrB 配列要素の変更に伴って arr 配列要素も変化

2. 深いコピー ( のみ第 1 レベルのディープ コピーを実行します)

注: ディープ コピーを使用する場合は、第 1 レベルのオブジェクト属性または配列要素のみをディープ コピーするか、オブジェクトのプロパティと再帰的にコピーするかなど、ディープ コピーの要件を明確にする必要があります。すべてのレベルの配列要素?

ディープ コピー配列

①. ダイレクト トラバーサル

var arr = [1, 2, 3, 4];
function copy(arr){
    var newArr = [];
    for(var i=0;i<arr.length;i++){
        newArr.push(arr[i]);
    }
    return newArr;
}
 
var arrB = copy(arr);
console.log("arrB:", arrB);
console.log("-----------改变arrB中数组元素的值后-----------");
arrB[0] = 5;
console.log("arr:", arr);
console.log("arrB:", arrB);

実行結果: arrB 配列要素の変更は、arr 配列要素の値に影響しません

②.concat():複数の配列を接続するために使用します。このメソッドは既存の配列を変更せず、単に連結された配列のコピーを返します。

var arr = [0, 1, 2];
var arrB;
 
//把arr赋值给arrB
arrB = arr.concat();
console.log("arr:", arr);
console.log("arrB:", arrB);
console.log("-----------改变arrB中数组元素的值后-----------");
arrB[0] = 5;
console.log("arr:", arr);
console.log("arrB:", arrB);

実行結果: arr 配列の要素は、arrB 配列の要素の変更に伴って変更されていません

③. slide(): このメソッドは、からインターセプトされた要素のフラグメントを返します。既存の配列を使用して新しい配列を形成します (元の配列は変更されません)。

var arr = [0, 1, 2, 4, 5];
var arrB;
 
//把arr赋值给arrB
arrB = arr.slice();
console.log("arr:", arr);
console.log("arrB:", arrB);
console.log("-----------改变arrB中数组元素的值后-----------");
arrB[0] = 10;
arr[4] = 8;
console.log("arr:", arr);
console.log("arrB:", arrB);

実行結果: 配列内の要素の変更は相互に影響しません

上記の 3 つのメソッドは、配列要素が基本データ型である単純な配列にのみ適用されます。配列要素、つまりオブジェクトである場合、または配列などの参照型変数の配列の場合、上記のメソッドは失敗します。

関連する推奨事項: JavaScript 学習チュートリアル

以上がJavaScriptのディープコピーとシャローコピーの違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。