JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptは値渡し?参照渡し?オブジェクトの受け渡しの仕組みをわかりやすく解説

JavaScriptは基本的に「値渡し(pass by value)」の言語です。しかし、オブジェクトに関しては少し特殊で、渡される「値」の中身が参照(リファレンス)そのものになっています。この仕組みを理解すると、関数にデータを渡したときの挙動が明確になります。

プリミティブ型(数値など)を渡した場合

まず、数値などのプリミティブ型を例に見てみましょう。関数に引数として渡した値を関数内で変更しても、呼び出し元の変数には一切影響しません。

コード例

let i = 0;
function increment(x) {
    x = x + 1
    console.log(x)
}
increment(i)
console.log(i)

実行結果

1
0

このように、関数内ではxの値が「1」に更新されていますが、呼び出し元のiは元の「0」のままです。これは、引数として値のコピーが渡されているためです。

オブジェクトを渡した場合

オブジェクトの場合はどうでしょうか。ポイントは次の2つです。

  • 関数内で引数の参照先を別のオブジェクトに付け替えても、元のオブジェクトには影響しない。
  • 一方、関数内でオブジェクトの内部状態(プロパティ)を変更すると、その変更は元のオブジェクトにも反映される。

コード例

let obj = {'foo': 'bar'};
function updateRef(x) {
    // xのローカルな参照だけが更新され、objには影響しない
    x = {}
}
function addHelloWorld(y) {
    // yが参照しているオブジェクトに新しいプロパティを追加する
    y['hello'] = 'world';
}
console.log(obj)
updateRef(obj)
console.log(obj)
addHelloWorld(obj)
console.log(obj)

実行結果

{ foo: 'bar' }
{ foo: 'bar' }
{ foo: 'bar', hello: 'world' }

結果の解説

最初の関数updateRefでは、ローカル変数xが新しい空のオブジェクトに再代入されただけなので、元のobjは無傷のままです。

一方、2番目の関数addHelloWorldでは、yobjと同じオブジェクトを参照しているため、そこにプロパティ'hello'を追加すると、元のオブジェクトの内部状態が直接変更されました。

まとめ

JavaScriptはあくまで「値渡し」の言語ですが、オブジェクトの場合その「値」が参照であるため、次のように挙動を使い分けて考えるとよいでしょう。

  • プリミティブ型(数値・文字列・真偽値など):コピーされた値が渡されるため、関数内での変更は呼び出し元に影響しない。
  • オブジェクト(配列・関数などを含む):参照が値として渡されるため、内部状態への変更は共有されるが、参照自体の再代入は影響しない。
  1. JavaScriptのRegExp(正規表現)オブジェクトとは?基本の使い方をわかりやすく解説

    RegExp(正規表現)オブジェクトは、テキストに対してパターンマッチングを行い、目的の文字列部分を検索・抽出するために使用されます。JavaScriptでは、RegExpオブジェクトを「RegExpコンストラクタ」または「リテラル構文」の2通りの方法で作成できます。 RegExpオブジェクトの作成方法 コンストラクタを使用する場合: new RegExp(pattern) リテラル構文を使用する場合: /pattern/ 主なメソッド test():文字列がパターンに一致するかどうかを真偽値(true / false)で返します。 exec():パターンに一致した文字列を返します。

  2. JavaScriptのオブジェクト初期化子とは?使い方をサンプルコードで解説

    オブジェクト初期化子とは オブジェクト初期化子(Object Initializer)は、新しく生成したオブジェクトを初期化するための式です。波括弧 {} の中に、「プロパティ名」と「それに対応する値」のペアを0個以上、カンマ区切りで列挙して記述します。 これにより、変数宣言と同時にオブジェクトの中身を簡単に定義することができます。 以下は、JavaScriptでオブジェクト初期化子を使用したサンプルコードです。 サンプルコード <!DOCTYPE html> <html lang="en"> <head> <meta chars