はじめに
コジマです。
JavaScriptで値渡しをする方法についてまとめます。
JavaScriptに参照渡し、値渡しの概念がないみたいな話も聞きますが、
ここではあえてこのような表現をいたします。
円周率は3.14だよという気持ちで見てください。
JavaScriptは参照渡し?
配列やオブジェクトを何の気なしに「=」で更新しようとすると参照渡しされてしまいます。
一時的にtmpに避けておきたいと思ったのに、
配列
参照渡しサンプル
コピー先が釣られて値変わるパターン
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const arr1 = [1, 2, 3, 4, 5] // 参照渡し const arr2 = arr1 // arr1を更新する arr1[0] = 10 // arr1が更新されていることの確認 console.log(arr1) // obj2が更新されてしまうことの確認 console.log(arr2) |
1 2 |
> Array [10, 2, 3, 4, 5] > Array [10, 2, 3, 4, 5] |
コピー元が釣られて値変わるパターン
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const arr1 = [1, 2, 3, 4, 5] // 参照渡し const arr2 = arr1 // arr2を更新する arr2[0] = 10 // arr1が更新されてしまうことの確認 console.log(arr1) // obj2が更新されていることの確認 console.log(arr2) |
1 2 |
> Array [10, 2, 3, 4, 5] > Array [10, 2, 3, 4, 5] |
値渡しサンプル
slice関数が使えます。
コピー元の配列から引数で与えた範囲を値渡しでコピーできます。
引数なしだと全範囲対象となるので、ここであ引数を与えずに丸コピします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const arr1 = [1, 2, 3, 4, 5] // 値渡し const arr2 = arr1.slice() // arr2を更新する arr2[0] = 10 // arr1が更新されていないことの確認 console.log(arr1) // obj2が更新されていることの確認 console.log(arr2) |
1 2 |
> Array [1, 2, 3, 4, 5] > Array [10, 2, 3, 4, 5] |
オブジェクト
参照渡しサンプル
コピー先が釣られて値変わるパターン
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const obj1 = { a: 1, b: 2 } // 参照渡し const obj2 = obj1 // obj1を更新する obj1.a = 10 // obj1が更新されていることの確認 console.log(obj1) // obj2が更新されてしまうことの確認 console.log(obj2) |
1 2 |
> Object { a: 10, b: 2 } > Object { a: 10, b: 2 } |
コピー元が釣られて値変わるパターン
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const obj1 = { a: 1, b: 2 } // 参照渡し const obj2 = obj1 // obj2を更新する obj2.a = 10 // obj1が更新されてしまうことの確認 console.log(obj1) // obj2が更新されていることの確認 console.log(obj2) |
1 2 |
> Object { a: 10, b: 2 } > Object { a: 10, b: 2 } |
値渡しサンプル
assign関数が使えます。
元の関数に対して引数で与えたオブジェクトを上書きしていく関数です。
コピー元のオブジェクトに空のオブジェクトを使用することで値渡しの
オブジェクトのコピーを作成できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const obj1 = { a: 1, b: 2 } // 値渡し const obj2 = Object.assign({}, obj1) // obj2を更新する obj2.a = 10 // obj1が更新されていないことの確認 console.log(obj1) // obj2が更新されていることの確認 console.log(obj2) |
1 2 |
> Object { a: 1, b: 2 } > Object { a: 10, b: 2 } |
さいごに
今回の話まとめます。
- 配列やオブジェクトで「=」で代入すると意図しない動作するときあるよ
- 配列の値渡しにはslice関数が使えるよ
- オブジェクトの値渡しにはassign関数が使えるよ
この記事を面白いまたは役に立ったと思ってくれた方は是非私のTwitter(@kojimanotech)を
フォローしてくれたらうれしいです!
以上、コジマでした。