1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScript における関数呼び出し時の引数渡しの挙動

Last updated at Posted at 2025-04-30

概要

JavaScript では、関数に引数を渡す際の挙動が「プリミティブ型」と「オブジェクト型(配列を含む)」で異なります。
本記事では具体例を挙げながら解説します。

プリミティブ型

数値や文字列、真偽値などのプリミティブ型は、関数内で再代入しても、呼び出し元の変数には影響しません。

function inc(x) {
  x = x + 1;
  console.log("関数内:", x);  // 関数内: 2
}
let a = 1;
inc(a);
console.log("呼び出し元 a:", a);  // 呼び出し元 a: 1

オブジェクト型(配列含む)は「参照のコピー」が渡される

  • 関数内でプロパティ/要素を変更すると、呼び出し元のオブジェクト/配列にも影響が及ぶ
  • 関数内で引数変数を別のオブジェクト/配列に再代入しても、呼び出し元の参照は変わらない

オブジェクトの場合

function setName(o) {
  o.name = "太郎";           // (A) 呼び出し元 person.name が "太郎" に
  o = { name: "次郎" };     // (B) o を新しいオブジェクトに再代入
  console.log("関数内 o:", o.name); // 関数内 o: 次郎
}

let person = { name: "一郎" };
setName(person);
console.log("呼び出し元 person:", person.name); // 呼び出し元 person: 太郎
  • (A) では、o.name = "太郎" によって呼び出し元の person.name も "太郎" になる
  • (B) の o = {…} は関数内の変数 o に新しい参照を割り当てるだけで、呼び出し元の person は変わらない

配列の場合

function modifyArray(arr) {
  // (1) 要素の変更は呼び出し元にも反映
  arr[0] = "B";

  // (2) 変数自体を再代入しても呼び出し元には影響なし
  arr = ["X", "Y", "Z"];
  console.log("関数内 arr の再代入後:", arr); // ["X","Y","Z"]
}

let original = ["A","A","A"];
modifyArray(original);
console.log("呼び出し元 original:", original); // ["B","A","A"]
  • (1) の arr[0] = "B"によって、呼び出し元 original[0]"B"
  • (2) の arr = […]はローカル変数の再代入なので、original には影響しない

スプレッド構文で配列をコピーするときの挙動(浅いコピー)

関数の引数ではないですが、スプレッド構文 [...] を使うと、新しい配列オブジェクトが作成されます。
しかし、その要素として格納されるオブジェクト自体は元の配列と同じ参照となる「浅いコピー(shallow copy)」になります。

たとえば以下の例を見てみましょう。

const original = [{ name: "A" }, { name: "B" }];
const shallowCopy = [...original];

// 配列自体は別インスタンス
console.log(original === shallowCopy); // false

// 要素(オブジェクト)は同じ参照
console.log(original[0] === shallowCopy[0]); // true

// shallowCopy に要素を追加しても original には影響しない
shallowCopy.push({ name: "C" });
console.log(original.length);    // 2
console.log(shallowCopy.length); // 3

// しかし要素のプロパティを変更すると original も変わる
shallowCopy[0].name = "Z";
console.log(original[0].name); // "Z"

上記のとおり、shallowCopy 自体は別の配列です。

shallowCopy.push(...) で要素を足しても元配列 original は変わらなりません。
しかし、配列内のオブジェクトを直接操作すると同じオブジェクトを参照しているため、original の中身も変化するという挙動になります。

まとめ

プリミティブ型

再代入しても呼び出し元は変わらない

オブジェクト型/配列

「参照のコピー」が渡され、プロパティや要素の変更は呼び出し元にも反映される。
一方、引数変数自体の再代入は影響しない

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?