JavaScript が参照渡しか値型渡しか

Sahil Bhosale 2024年2月15日
  1. JavaScript のプリミティブデータ型は値渡しです
  2. JavaScript の非プリミティブ値は参照によって渡される
  3. JavaScript は値渡しと参照渡しの両方です
JavaScript が参照渡しか値型渡しか

JavaScript プログラミング言語が参照型による受け渡しであるかどうかを深く掘り下げる前に、まず値による受け渡しと参照による受け渡しの違いを見てみましょう。

これらのことは、通常、割り当て操作を行っているとき、または関数自体を処理しているときに思い浮かびます。ほとんどの場合、代入演算を実行し、さまざまな関数を作成し、これらの関数に複数の変数を渡します。これらが内部でどのように機能するかを知ることで、プログラミング言語をより深く理解できます。

変数の値を別の変数または関数に割り当てたり渡したりする場合は常に、値渡しと呼ばれます。変数のアドレスを別の変数または関数に割り当てたり渡したりする場合、それは参照渡しと呼ばれます。

値渡しタイプと参照渡しタイプの基本的な定義を確認したので、以下の例でそれらがどのように使用されるかをさらに理解しましょう。

JavaScript のプリミティブデータ型は値渡しです

JavaScript には、プリミティブデータ型と非プリミティブデータ型の 2 種類のデータ型があることに注意してください。プリミティブデータ型は、数値、ブール値、文字列、未定義、および null で構成されます。

これらのデータ型には、オブジェクトや配列のように事前定義されたメソッドはありません。プリミティブデータ型は不変です。つまり、あるプリミティブ変数の値を別のプリミティブ変数に格納または割り当て、2 番目の変数の値に変更を加えても、最初の変数の値は変更されません。その変数自体の値を変更しない限り、そのままになります。そうして初めて、2 番目の変数が変更されます。

プリミティブデータ型に関連する詳細については、MDN を参照してください。

// Example 1
let a = 10;
let b = a;
b = b + 1;

console.log(a);
console.log(b);


// Example 2
let name = 'Google';

let greet =
    (val) => {
      val = 'Hi ' + name + '!';
      return val;
    }

             console.log(name);
console.log(greet(name));

出力:

10
11
Google
Hi Google!

上記のコードは、下の図の助けを借りてよりよく理解することができます。最初のコード例のみを説明していることに注意してください。2 番目の例は、例 1 とほぼ同じように機能します。

プリミティブ型の例の視覚化

最初の例では、ab の 2つの変数があります。変数 a10 の数値を割り当てました。これにより、メモリ内の変数 a にスペースが割り当てられ、アドレス 0x01(この例では任意のアドレス)を持つ黄色で表されます。

次に、変数 a を変数 b に割り当てます。このプロセスは、変数 b に新しいメモリスペースを割り当てます。ここでは、変数 a の値(10)が格納されます。

上記の例から、変数 ab の両方のアドレスが異なることがはっきりとわかります。これは、それらがメモリ内に異なるスペースを割り当てていることを意味します。この結果は、変数 b の値を b = b + 1 として変更または変更しても、変数 a 内の値は変更されないことを意味します。変数 b の値のみが変更され、1 ずつインクリメントするため、11 になります。

2 番目の例では、値 Google を持つ変数 name があります。greet() と呼ばれる関数もあります。この関数は、引数として文字列値を取り、新しい文字列を返します。この関数の引数として、変数 a を渡します(変数を渡すことは、アドレスではなく値を渡すことを意味することに注意してください)。Google 値は、val という名前の関数のローカル変数内に格納されます。

現在、変数 val は値 Google を保持しています。関数では、この値を Hi Google!に変更しています。次に、この値を返します。ここで、name 変数の値と関数の両方を戻り値とともに出力すると、両方が異なります。変数 nameval の両方が異なる場所に格納され、値 Google のみを関数とアドレスに渡すため、name 変数は変更されません。

以前、値渡しの定義を見てきました。これは、変数の値を代入中または関数に渡すときにのみ渡すというものです。上記の 2つの例は、実際にそれを示しています。

JavaScript の非プリミティブ値は参照によって渡される

非プリミティブデータ型は、配列、オブジェクト、またはクラスで構成されます。これらのデータ型には、配列またはオブジェクト内のデータを操作できるようにする事前定義された組み込み関数があります。

プリミティブデータ型は変更可能です。これは、後で変更できるデータ型が可変として知られていることを意味します。さらに、非プリミティブデータ型は参照によって呼び出されます。以下の例でこれを理解しましょう。

let a = [1, 2];
let b = a;
b.push(3);

console.log(a)
console.log(b)

出力:

[ 1, 2, 3 ]
[ 1, 2, 3 ]

上記の例の画像は次のとおりです。

非 premitiv タイプの例

この例では、[1,2] という 2つの要素を持つ配列 a を作成しました。配列は非プリミティブデータ型であるため、変数 a はすべての配列要素を格納するわけではありません。代わりに、値 [1,2] がメモリ内の別の場所に保存されます。この場合、上の図に示すように、その配列の開始アドレス(この場合は 0x01)は変数 a に格納されます。変数 a には実際の配列要素が格納されているアドレスがあるため、その場所を指します。

変数 a を変数 b に割り当てると、a 内に存在するアドレスが変数 b に格納されます。これで、変数 b も変数 a と同じメモリ位置 0x011 を指すようになります。これは、両方が同じメモリアドレスを持っているためです。したがって、b が指す配列の要素を変更すると、両方が同じ場所を指しているため、a も影響を受けます。

ここでは、b.push(3) などの変数 b を使用して、新しい要素を配列にプッシュしています。これで、変数 b は、最初の要素 1 から最後の要素 2 まで配列全体をトラバースします。最後の要素の後に、新しい要素 3 を配列に挿入します。変数 ab の両方を出力すると、参照のため、両方とも [1,2,3] と同じ値を示すことがわかります。

これは、値ではなくメモリアドレス自体を渡すため、参照渡しと呼ばれます。

JavaScript は値渡しと参照渡しの両方です

JavaScript プログラミング言語は、値渡しと参照渡しの両方をサポートしています。数値、ブール値、文字列、未定義、null などのプリミティブ値はすべて値によって渡されます。配列、オブジェクト、クラスなどの非プリミティブ型は、参照によって渡されます。

著者: Sahil Bhosale
Sahil Bhosale avatar Sahil Bhosale avatar

Sahil is a full-stack developer who loves to build software. He likes to share his knowledge by writing technical articles and helping clients by working with them as freelance software engineer and technical writer on Upwork.

LinkedIn