0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScriptの参照とコピーについて

Last updated at Posted at 2022-12-13

はじめに

プログラミング言語において参照やコピーは基礎の基礎。しかし私はJavaScriptを書いていてよく混乱することが多いので整理のためにも、参照とコピーについてまとめたいと思います。

プリミティブ型とオブジェクトの参照

まずはプリミティブ型とオブジェクトの参照についてみていきます。

//プリミティブ型の参照
let num = 1;
num = 2;
console.log(num); // 2

//オブジェクト型の参照
let obj = {
  a: "hello",
}
obj.a = "world";
console.log(obj.a); // world

プリミティブ型の参照は、変数numに1が記録されたメモリのアドレスが代入されています。この状態を『参照』と言い、そして変数numに2を再代入する時は、1が記録されていたメモリに2が上書きされ参照先自体は変わりません。

オブジェクトの参照は、objに"hello"が格納されたメモリのアドレスを参照するaが保持されていることになります。なのでオブジェクトは『データをキーと値のペアで管理するもの』と定義されることがありますが、『データのアドレスに名前をつけて管理するもの』とも言えます。

参照とコピー

次に参照とコピーとその注意点についてです。
下記のコードでは変数numの値を変数num2にコピーしnum2の値を変更しています。

//プリミティブ型の参照
let num = 1;
let num2 = num;
num2 = 2;

console.log(num); // 1
console.log(num2); // 2

//オブジェクト型の参照
let obj = {
  a: "hello",
}
let obj2 = obj;
obj2.a = "world";
console.log(obj.a); // world
console.log(obj2.a); //world

ここでコピーされたnumnum2の値を確認すると値が違います。numからnum2へコピーした時は、numの参照先の値をコピーし複製した新しい参照先のものがnum2へ保持されています。
しかし、オブジェクト型の参照の実行結果を見ると出力結果が同じになっています。

これはobjからobj2へ値を代入する際の挙動に差異があるからです。
オブジェクトを新しくコピーしようとした際にプリミティブ型のように新しいものが複製されるのではなく、参照先が同じオブジェクトが作成されているのです。つまり、オブジェクトの名前が違うだけで参照する値は同じものになります。

このようにプリミティブ型とオブジェクト型の参照とコピーには差異があり、この違いをしっかりと理解していないとJavaScriptを学んでいく中でつまづくことが多くなってしまいます(私のことです)。

参照と引数

ここからが非常に面白く、実は上記で説明させていただいた参照とコピーは関数へ引数を渡す際も同様のことが起きています。

// プリミティブ型を引数として渡す

let name = "marumoto";

function updateName(nameA) { 
  console.log(nameA); // marumoto
  nameA = "shoma";
  console.log(nameA); // shoma
};

updateName(name);
console.log(name); // marumoto


// オブジェクトを引数として渡す
let user = {
  name: "marumoto",
}
  
function updateUserName(userA) {
  console.log(userA.name); // marumoto
  userA.name = "shoma";
  console.log(userA.name); // shoma
};
  
updateUserName(user);
console.log(user.name); // shoma

ここでの両者の違いも同様に

  • プリミティブ型の値を関数へ渡した時は、関数スコープ内で使用する変数は引数として受け取った変数とは違う変数
  • オブジェクトを関数へ渡した時は、参照先のアドレスが渡されるので引数として渡ってきたものと同じオブジェクト
    という参照とコピーの法則が適用されるようになります。

最後に

いかがだったでしょうか、今回は私がJavaScriptを勉強していて理解が難しかった参照とコピーについてまとめてみました。

同じように見えるものでも実は背景では違うものとして扱われていて、とても分かりにくいとは思いますが、ここを理解しておくとバグを防ぐことができるのでしっかりと意識していきたいところだと思っています。

GoQSystemでは一緒にはたらいてくれる仲間を募集中です!

ご興味がある方は以下リンクよりご確認ください。

0
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?