PORTFOLIO & WEB DESIGN MEMORANDOM BLOG   
PORTFOLIO & WEB DESIGN MEMORANDOM BLOG   

【JavaScript】JavaScript のアロー関数と、argumentsオブジェクトについて

JavaScript のアロー関数は、function キーワードを使わずに関数を定義するための短縮構文です。

基本構文

  1. (param1, param2, ..., paramN) => {
  2.   // 関数の処理
  3.   return result;
  4. };

パラメータが1つの場合: 括弧を省略できます。

  1. param => param * 2;

パラメータがない場合: 空の括弧が必要です。

  1. () => console.log("Hello");

関数本体が1つの式の場合: {}(ブロック)と return キーワードを省略できます。

  1. //通常の関数
  2. function add(a, b) {
  3.   return a + b;
  4. }
  5. console.log(add(2, 3)); // 5
  6. //アロー関数
  7. const add = (a, b) => a + b;
  8. console.log(add(2, 3)); // 5

アロー関数の特徴

1.短い構文

通常の関数定義より簡潔に書けるため、特にコールバック関数や短い関数でよく使われます。

  1. // 通常の関数
  2. let add = function(a, b) {
  3.   return a + b;
  4. };
  5. // アロー関数
  6. let add = (a, b) => a + b;

2.thisの扱い

アロー関数は通常の関数とは異なり、自身のthisを持たず、囲んでいるスコープのthisを継承します。このため、クラス内で使うときなどに便利です。

  1. function Person() {
  2.   this.age = 0;
  3.   setInterval(() => {
  4.     this.age++; // アロー関数はPersonオブジェクトの`this`を継承
  5.   }, 1000);
  6. }
  7. let p = new Person();

通常の関数の場合、thisはグローバルオブジェクト(ブラウザではwindow)を指します。

3.コンストラクタとして使えない

アロー関数は new キーワードでインスタンスを作成するコンストラクタ関数としては使えません。

arguments オブジェクトがない

アロー関数は arguments オブジェクトを持ちません。
通常の関数では arguments で渡された引数にアクセスできますが、アロー関数ではアクセスできません。
代わりに、スプレッド構文を使用します。

  1. const sum = (...args) => {
  2.   return args.reduce((acc, curr) => acc + curr, 0);
  3. };

アロー関数でオブジェクトを返す方法

アロー関数でオブジェクトを返す場合、オブジェクトリテラルを () (丸括弧)で囲む必要があります。
そうしないと、JavaScriptは {} を関数のブロックと解釈してしまうからです。

  1. const getObject = () => ({ name: "John", age: 30 });
  2. console.log(getObject());
  3. // { name: "John", age: 30 }

{} を直接書くと関数のブロックとみなされるので、オブジェクトリテラルとして返したい場合は、全体を () で囲む必要があります。
上記の例では、アロー関数が1行でオブジェクト { name: “John”, age: 30 } を返しています。

関数本体に複数のステートメントがある場合

もし、複数のステートメントがある場合は {} を使って通常通りの関数ブロックを書き、その中で return を使ってオブジェクトを返します。

  1. const getObject = () => {
  2.   const name = "John";
  3.   const age = 30;
  4.   return { name, age };
  5. };
  6. console.log(getObject());
  7. // { name: "John", age: 30 }

この場合、関数本体には複数のステートメントが含まれているため、{} のブロックと return を明示的に使っています。

使用例

1.コールバック関数での使用

  1. let numbers = [1, 2, 3];
  2. let doubled = numbers.map(num => num * 2);
  3. console.log(doubled); // [2, 4, 6]

2.thisの継承を活かす例

  1. function Counter() {
  2.   this.count = 0;
  3.   setInterval(() => {
  4.     this.count++;
  5.     console.log(this.count); // `this`はCounterオブジェクトを指す
  6.   }, 1000);
  7. }
  8. let counter = new Counter();

アロー関数は、その簡潔さと this の扱いが特徴で、特にコールバック関数や非同期処理などで使われることが多いです。

通常の関数とアロー関数の比較

this の違い

  1. // 通常の関数
  2. function Person() {
  3.   this.age = 0;
  4.   setInterval(function() {
  5.     this.age++;
  6.     console.log(this.age); // NaN: `this`はグローバルオブジェクト(ブラウザでは`window`)を指す
  7.   }, 1000);
  8. }
  9. let p = new Person();

上記のコードでは、setInterval 内の通常の関数は this をグローバルオブジェクトとして扱います。
したがって、this.age は未定義で、this.age++ は NaN になります。
this を意図した Person インスタンスにバインドするためには bind を使用するか、self などの変数を使ってthis を保存する必要があります。

これをアロー関数で書き換えると、this が期待通りに機能します。

  1. // アロー関数
  2. function Person() {
  3.   this.age = 0;
  4.   setInterval(() => {
  5.     this.age++;
  6.     console.log(this.age); // 正常に年齢が増える。`this` は `Person` オブジェクトを指す
  7.   }, 1000);
  8. }
  9. let p = new Person();

アロー関数では、this はアロー関数を囲むスコープ(この場合は Person オブジェクト)を参照します。
そのため、this.age++ は期待通り動作し、this の扱いを簡単にできます。

arguments オブジェクトの違い

  1. // 通常の関数
  2. function showArguments() {
  3.   console.log(arguments); // 引数のリストを表示する
  4. }
  5. showArguments(1, 2, 3); // [1, 2, 3]

通常の関数では arguments オブジェクトを使って、渡された引数にアクセスできます。これは明示的に引数を指定しなくても、すべての引数にアクセス可能です。

アロー関数では arguments は存在しませんが、代わりにスプレッド構文(…)を使うことができます。

  1. // アロー関数
  2. const showArguments = (...args) => {
  3.   console.log(args); // スプレッド構文を使用して引数のリストを表示する
  4. };
  5. showArguments(1, 2, 3); // [1, 2, 3]

アロー関数では arguments がないため、スプレッド構文を使う必要があります。スプレッド構文により、アロー関数でも同様に複数の引数にアクセスできます。

比較まとめ

this の扱い: 通常の関数は実行時に this が決定され、アロー関数は囲んでいるスコープの this を継承します。

arguments の扱い: 通常の関数は arguments オブジェクトで引数にアクセスできますが、アロー関数はそれを持たず、代わりにスプレッド構文を使います。

arguments オブジェクトとは

arguments オブジェクトは、関数に渡された全ての引数を配列のような形で保持する特殊なオブジェクトです。

主に、関数の定義に指定された引数の数に関係なく、実際に渡された引数にアクセスするために使われます。

特徴

配列のようだが配列ではない: arguments は配列に似ていますが、実際にはオブジェクトです。配列のようにインデックス(arguments[0], arguments[1])を使ってアクセスできますが、配列のメソッド(forEach や map など)は使用できません。

全ての引数を保持: 関数に渡された引数の数に関係なく、すべての引数が arguments に格納されます。関数のパラメータに指定されていない引数にもアクセス可能です。

length プロパティ: arguments には length プロパティがあり、関数に渡された引数の数を返します。

ES5 以前に便利: ES6 以降、スプレッド構文(…args)が導入されたため、スプレッド構文の方がモダンな書き方として推奨されます。しかし、古いコードでは arguments が広く使用されています。

使用例

通常の関数での arguments の使い方は以下になります。

  1. function sum() {
  2.   let total = 0;
  3.   for (let i = 0; i < arguments.length; i++) {
  4.     total += arguments[i]; // `arguments[i]` で各引数にアクセス
  5.   }
  6.   return total;
  7. }
  8. console.log(sum(1, 2, 3, 4)); // 10

この例では、関数 sum に渡された引数の数を気にせず、すべての引数を arguments を使って合計しています。

以下の例は、パラメータと一致しない引数にアクセスする例です。

  1. function showFirstTwo(a, b) {
  2.   console.log(a); // 1
  3.   console.log(b); // 2
  4.   console.log(arguments[2]); // 3: パラメータに指定されていないが、3番目の引数にアクセスできる
  5. }
  6. showFirstTwo(1, 2, 3);

この例では、関数のパラメータとしては a と b しか指定していませんが、arguments オブジェクトを使って3番目の引数 3 にもアクセスしています。

arguments の制約とスプレッド構文の導入

ES6 では、arguments の代わりに スプレッド構文(…args) が推奨されています。これにより、引数を配列として簡単に扱えるようになりました。

スプレッド構文での例

  1. const sum = (...args) => {
  2.   return args.reduce((total, num) => total + num, 0);
  3. };
  4. console.log(sum(1, 2, 3, 4)); // 10

この例では、…args で渡された引数を配列として受け取り、そのまま reduce メソッドで合計を計算しています。
スプレッド構文を使うことで、arguments オブジェクトよりも直感的に引数を扱えるようになります。

argumentsのまとめ

・arguments はすべての引数を保持する特殊なオブジェクト。
・arguments は配列ではないが、配列のようにインデックスでアクセス可能。
・ES6 以降は、…args のようなスプレッド構文が使われることが多く、arguments よりも柔軟で使いやすい。

MILMONA   MILMONA   MILMONA   MILMONA   MILMONA   
MILMONA   MILMONA   MILMONA   MILMONA   MILMONA