ホームページ >ウェブフロントエンド >jsチュートリアル >jsの転送とコピーについて詳しく解説

jsの転送とコピーについて詳しく解説

小云云
小云云オリジナル
2018-03-13 16:12:281364ブラウズ

js にはいくつかの基本的なデータ型と、(オブジェクト、配列、関数) などの他の複雑なデータ型があることがわかっています。基本的なデータ型の割り当ては、実際には値のコピーと呼ばれます。割り当てられた変数は同じです。元のとおり 変数には、値が等しいという以外の関係はありません。

let x = 666
let y = x
let m = 'abc'
let n = m
y = 888
n = 'def'
console.log(x, y)//666,888
console.log(m, n)//'abc','def'

複素データ型の転送はこのようにはなりません。変数が複素データ型にバインドされている場合、記録されるのは複素データの値ではなく、データのアドレス情報であるときです。この変数は別の変数に代入され、実際にはデータ情報を指します。この転送メソッドを参照渡し

let obj1 = {
    a : '1',
    b : 2
} 
let obj2 = obj1
obj2.b = 3
console.log(obj1,obj2)//{a: "1", b: 3},{a: "1", b: 3}

Copy

と呼びます。

複雑なデータ型の割り当ては参照によって行われることがわかっています。実際のプロジェクトでは、これが起こることは望ましくないことがよくあります。

には 2 つのビューがあります。まず、リストはデータを順番に表示するだけで済みます。次に、グラフはデータを処理する前にデータを反転する必要があります。 reverse() の後の最初のリストも逆の順序になっています。これは、配列の値をコピーするだけのメソッドが必要であり、この新しい配列のデータ アドレスは異なります。このコピー メソッドは、配列のコピーと呼ばれます。

let obj1 = {a:1, b:{c:2}}
let shallowCopy = (src)=> {
    let dst = {}
    for (let prop in src) {
        if (src.hasOwnProperty(prop)) {
          dst[prop] = src[prop]
        }
    }
    return dst
}
let obj2 = shallowCopy(obj1)
console.log(obj1,obj2) //@1
obj1.a = 6
console.log(obj2.a) //@2
obj2.b.c = 666
console.log(obj1.b.c) //@3
obj2.b = {
    c: 888
}
console.log(obj1.b.c) //@4

上記の例から、obj1 の最初の層の属性は属性値をコピーし、アドレスのコピーを継承しないことがわかりますが、2 番目の層の b 属性はメモリ アドレスを共有します。浅いコピーですが、@4 では、属性 b がオブジェクトであるため、obj1 は obj2 の影響を受けません。参照転送によるこの種の再割り当てにより、コンピュータはデータを保存し、アドレス情報を記録するために新しいメモリを再割り当てします。そのため、この時点では obj1 です。 .b.c と obj2。b.c はレコードの属性値ではなくなりました

次のように理解することもできます。複雑なデータ型の直接割り当ては参照転送であり、コピーは単純なデータ バックアップとは言えません。コピーも浅いコピーと深いコピーに分かれているため、元のデータのメモリアドレス情報は完全に同じではありません。

複雑なデータ型のネストされていないコピーは、データ情報の最初の層のみがコピーされることを意味します。これは、データの最初の層が複雑なデータ型を持つ場合でも、参照転送方法が使用され、コピーはまだアドレス情報であり、他のメソッドで実装された配列オブジェクトなどの多層ネストされたコピーがディープコピーです。 Arraysとオブジェクトが深いコピーと浅いコピーをどのように実装するかを見てみましょう。演算子

let arr1 = [1,2,[3,4]]
let arr2 = arr1.slice(0)
arr2[2].push(5)
arr2.push(6)
console.log(arr1,arr2)

上記 4 種類の配列のコピーはすべて浅いコピーであり、配列の深いコピーを実現するには、再帰的に実装する必要があります

let arr1 = [1,2,[3,4]]
let arr2 = arr1.concat()
arr2[2].push(5)
arr2.push(6)
console.log(arr1,arr2)
    メソッド arr1[2] と arr2 がわかります。 [2] は異なり、上記と同じディープコピー copy メソッドはオブジェクトにも適用できます
  • オブジェクトのコピー

  • ユニバーサル for ループ

    let arr1 = [1,2,[3,4]]
    let arr2 = []
    for(let i = 0; i<arr1.length; i++){
        arr2.push(arr1[i])
    }
    arr2[2].push(5)
    arr2.push(6)
    console.log(arr1,arr2)
  • ...operator

    let arr1 = [1,2,[3,4]]
    let [...arr2] = arr1
    arr2[2].push(5)
    arr2.push(6)
    console.log(arr1,arr2)
  • Object.assign( )

    let deepClone = (src)=> {
        let result
        (src instanceof Array) ? (result = []) :(result = {})
        for (let key in src) {
            result[key] = (typeof src[key] === &#39;object&#39;) ? deepClone(src[key]) : src[key]//数组和对象的type都是object
        }
        return result
    }   
    let arr1 = [1,2,[3,4]]
    let arr2 = deepClone(arr1)
    arr2[2].push(5)
    arr2.push(6)
    console.log(arr1,arr2)

上記の 3 つのメソッドはオブジェクトです 浅いコピー、オブジェクトのディープ コピーの 2 つのメソッドを紹介します:

文字列に変換してからオブジェクトに戻す

let obj1 = {a:1,b:{c:2}}
let obj2 = {}
for(let key in obj1){
    obj2[key] = obj1[key]
}
obj1.b.c = 6
console.log(obj1,obj2)
  • deepClone メソッドは、上記の配列

  • 関連概念

  • 純粋関数
  • 外部環境に影響を与えることなく、関数に入力を与え、一意の出力を返す関数は、純粋関数と呼ばれ、その中で定義された変数は、によって再利用されます。関数が戻った後のガベージ コレクション メカニズム。

  • ただし、関数のパラメータが配列、オブジェクト、または関数の場合、参照が渡され、その操作が元のデータに影響を与えるため、この方法で記述された関数には副作用があり、可読性が低くなります。

影響を軽減する方法は、受信パラメータのディープ コピーを作成し、それらを新しい変数に割り当てて、元のパラメータが改ざんされるのを防ぐことです。

    純粋関数の例を見てみましょう:
  • let obj1 = {a:1,b:{c:2}}
    let {...obj2} = obj1
    obj1.b.c = 6
    console.log(obj1,obj2)

    上記の例を通して、wang の値が純粋関数によって変更されていないことがわかります。

  • もう一度次の例を考えてみましょう。正解した場合は、この記事の内容を深く理解していることになります(全員にリマインド -> 参照の再割り当て)
  • let obj1 = {a:1,b:{c:2}}
    let obj2 = Object.assign({},obj1)
    obj1.b.c = 6
    console.log(obj1,obj2)

    上記は私の js の理解です。ご理解ください。引用と送信が不適切な場合はご容赦ください。

  • 理解を深めたい場合は、他の記事もお読みください。JavaScript における価値とリファレンスの説明をお勧めします。

関連する推奨事項:

値でパラメータを渡す js 関数

JavaScript パラメータを渡すイラストチュートリアル

php と js で渡す json の簡単な分析

以上がjsの転送とコピーについて詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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