JavaScript参照渡し徹底解説!使いこなすための10のサンプルコード

JavaScript参照渡しのサンプルコードを学ぶJS

 

【当サイトはコードのコピペ・商用利用OKです】

このサービスはASPや、個別のマーチャント(企業)による協力の下、運営されています。

記事内のコードは基本的に動きますが、稀に動かないことや、読者のミスで動かない時がありますので、お問い合わせいただければ個別に対応いたします。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10000時間以上』を満たすプログラマ集団によって監修されています。

はじめに

この記事を読めば、JavaScriptの参照渡しを理解し、使いこなすことができるようになります。

10個のサンプルコードを通して、参照渡しの使い方や注意点を詳しく解説していきます。

●JavaScript参照渡しとは

JavaScriptにおける参照渡しとは、オブジェクトや配列などのデータ構造が他の変数や関数に渡される際に、そのデータ構造の実体ではなく参照が渡されることを指します。

○プリミティブ型とオブジェクト型の違い

JavaScriptには、プリミティブ型(基本型)とオブジェクト型(参照型)の2つのデータ型があります。

プリミティブ型には、数値、文字列、真偽値などがあり、オブジェクト型には、オブジェクト、配列、関数などがあります。

プリミティブ型は値渡し、オブジェクト型は参照渡しとなります。

値渡しでは、変数や関数に値がコピーされますが、参照渡しでは、オブジェクトや配列の参照が渡されるため、変更が他の変数や関数にも影響を与えます。

●JavaScript参照渡しの使い方

参照渡しを理解することで、データ構造の操作がスムーズになります。

下記に参照渡しの使い方をいくつかのサンプルコードで紹介します。

○サンプルコード1:オブジェクトの参照渡し

const obj1 = { a: 1, b: 2 };
const obj2 = obj1;

obj2.a = 10;

console.log(obj1); // { a: 10, b: 2 }
console.log(obj2); // { a: 10, b: 2 }

この例では、obj1の参照がobj2に渡されています。

そのため、obj2でプロパティaの値を変更すると、obj1の値も変わります。

○サンプルコード2:配列の参照渡し

const arr1 = [1, 2, 3];
const arr2 = arr1;

arr2[0] = 10;

console.log(arr1); // [10, 2, 3]
console.log(arr2); // [10, 2, 3]

この例では、arr1の参照がarr2に渡されています。

そのため、arr2でインデックス0の要素を変更すると、arr1の値も変わります。

○サンプルコード3:関数での参照渡し

function update(obj) {
  obj.value = 100;
}

const myObj = { value: 50 };
update(myObj);

console.log(myObj); // { value: 100 }

この例では、myObjの参照が関数updateに渡されています。

そのため、関数内でプロパティvalueの値を変更すると、myObjの値も変わります。

●応用例とサンプルコード

参照渡しを活用することで、効率的なプログラムを作成することができます。

下記に、参照渡しの応用例をいくつかのサンプルコードで紹介します。

○サンプルコード4:オブジェクトのマージ

function mergeObjects(obj1, obj2) {
  for (let key in obj2) {
    obj1[key] = obj2[key];
  }
}

const objA = { a: 1, b: 2 };
const objB = { b: 3, c: 4 };

mergeObjects(objA, objB);

console.log(objA); // { a: 1, b: 3, c: 4 }

この例では、objAobjBの参照が関数mergeObjectsに渡され、objAobjBのプロパティがマージされています。

○サンプルコード5:ディープコピー

function deepCopy(obj) {
  return JSON.parse(JSON.stringify(obj));
}

const originalObj = { a: 1, b: { c: 2 } };
const copiedObj = deepCopy(originalObj);

copiedObj.b.c = 10;

console.log(originalObj); // { a: 1, b: { c: 2 } }
console.log(copiedObj); // { a: 1, b: { c: 10 } }

この例では、originalObjをディープコピーして新しいオブジェクトcopiedObjを作成しています。

copiedObjのプロパティを変更しても、originalObjには影響がありません。

○サンプルコード6:配列のソート

function sortByKey(arr, key) {
  arr.sort((a, b) => a[key] - b[key]);
}

const data = [
  { id: 3, value: 10 },
  { id: 1, value: 50 },
  { id: 2, value: 30 },
];

sortByKey(data, 'id');

console.log(data);
// [{ id: 1, value: 50 }, { id: 2, value: 30 }, { id: 3, value: 10 }]

この例では、オブジェクトの配列dataの参照が関数sortByKeyに渡され、指定されたキー(この場合はid)でソートされています。

○サンプルコード7:配列の操作

function removeElement(arr, index) {
  arr.splice(index, 1);
}

const myArray = [1, 2, 3, 4, 5];
removeElement(myArray, 2);

console.log(myArray); // [1, 2, 4, 5]

この例では、myArrayの参照が関数removeElementに渡され、指定されたインデックスの要素が削除されています。

○サンプルコード8:関数内でのオブジェクト操作

function changeObject(obj) {
  obj.name = 'Alice';
  obj.age = 25;
}

const person = { name: 'Bob', age: 30 };
changeObject(person);

console.log(person); // { name: 'Alice', age: 25 }

この例では、personオブジェクトの参照が関数changeObjectに渡され、関数内でnameageプロパティが変更されています。

●注意点と対処法

参照渡しは、オブジェクトや配列を操作する際に便利ですが、注意点もあります。

下記に注意点と対処法を説明します。

変更が他の変数や関数に影響を与える

参照渡しを使うと、操作が他の変数や関数にも影響を与えることがあります。

この問題を解決するために、オブジェクトや配列をコピーして新しい参照を作成することができます。

ただし、単純な代入ではシャローコピーになるため、ディープコピーを行う方法(サンプルコード5参照)を使用してください。

関数内でのオブジェクトや配列の変更が直感に反する場合

関数内でオブジェクトや配列を変更すると、関数外の変数や他の関数にも影響を与えることがあります。

関数内での変更が直感に反する場合は、関数の戻り値として新しいオブジェクトや配列を作成し、呼び出し元で適切に処理することが望ましいです。

●カスタマイズ方法

参照渡しの仕組みを利用して、さまざまなカスタマイズが可能です。

下記にカスタマイズの例をいくつか紹介します。

○サンプルコード9:オブジェクトを拡張する関数

function extendObject(target, ...sources) {
  for (const source of sources) {
    for (const key in source) {
      target[key] = source[key];
    }
  }
}

const base = { a: 1, b: 2 };
const extension1 = { b: 3, c: 4 };
const extension2 = { d: 5 };

extendObject(base, extension1, extension2);

console.log(base); // { a: 1, b: 3, c: 4, d: 5 }

この例では、extendObject関数を使って複数のオブジェクトをマージして、新しいオブジェクトを作成しています。

○サンプルコード10:クロージャでの参照渡し

function createCounter() {
  const state = { count: 0 };

  return {
    increment: function() {
      state.count += 1;
    },
    getCount: function() {
      return state.count;
    }
  };
}

const counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.getCount()); // 2

この例では、クロージャを使って参照渡しを利用し、プライベートなstateオブジェクトを操作するインクリメント機能を持つカウンターを作成しています。

まとめ

この記事では、JavaScriptでの参照渡しを徹底解説し、その仕組み、使い方、対処法、注意点、カスタマイズ方法について説明しました。

また、さまざまな応用例とサンプルコードも紹介しました。

この記事を読めば、参照渡しを活用して、効率的で柔軟なコードを書くことができるようになります。

参照渡しはJavaScriptの重要な概念であり、理解しておくことで、コードの品質やメンテナンス性が向上するでしょう。

ぜひこの知識を活かして、JavaScriptのプログラミング力を向上させてください。