0
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】apply メソッドについて

Last updated at Posted at 2024-12-19

applyメソッドと似ているメソッドとしてcallメソッドがあります。

主な違いはapplyメソッドは第 2 引数以降は一つの引数を受け取るのに対し、callメソッドは第 2 引数以降複数の引数を受けとれるということです。

ここではapplyについて、私が理解した範囲内で書いていきます。

まず apply メソッドの構文です。

func.apply(thisArg, [argsArray]);

MDN サイトに記載されているものをそのまま持ってきました。私の理解を交えながら説明します。

applyメソッドは、ある関数funcから呼び出すことができます。

第 1 引数のthisArgfunc関数内のthisの新たな参照先です。

func内でthisが呼び出されていない場合、thisArgにはnullまたはundefinedを代入することも可能です。

第 2 引数のargsArrayは配列風のオブジェクト?で、func関数が呼ぶことになる引数を列挙したものになります。

例えばfn1(a, b, c)という関数において、関数fn1内のthisを関数fn2に向けたい場合、applyを使うとfn1.apply(fn2, [a, b, c])のようになります。

applyメソッドの使い方を具体例で見てみます。

function User(name) {
  this.name = name;
}
User.prototype.getName = function () {
  return this.name;
};

const user1 = new User("太郎");
const user2 = new User("花子");

console.log(user1.getName()); // 太郎
console.log(user2.getName()); // 花子
console.log(user1.getName.apply(user2)); // 花子

applyは、applyメソッドを呼び出した関数内のthisのあて先を、applyメソッドの第 1 引数で渡したオブジェクトに向けなおす機能があります。

上記コードでは、Userというコンストラクタ関数を作成しました。

user1 では name 属性として「太郎」、user2 では name 属性として「花子」を格納しました。

さらに name を取得する getName メソッドを定義しました。

user1.getName()user2.getName()では、getName メソッドを呼び出しているオブジェクトが所持している name を返しています。

しかしuser1.getName.apply(user2)では、getName を呼び出している user1 の name ではなく、applyの第 1 引数である user2 の name を返しています。

これは、getName メソッド内のthisの参照先がapplyメソッドによって user1 から user2 に変更されたからだとわかります。

const numbers = [4, 9, 1, 6, 8, 3];

const max = Math.max.apply(null, numbers);
console.log(max); // 9

もしapplyの役割として「thisの参照先を変える」しか知らないと、上記のMath.max.apply(null, numbers)の第 1 引数としてnullを見た瞬間、「thisの参照先をなくしているからapplyの意味ないじゃない?」と思うはずです。

これは先ほど述べたように、Math.max関数内ではthisを使用していないため、nullを渡しても問題ないからです。

ではここでapplyを使った意味は何でしょうか?

もし単純に numbers 配列内の最大要素を求めようとして、Math.max(numbers)とすると、NaNが返されます。

これは Math.max メソッドはMath.max(1,2,3,4,5)みたいに引数を代入する必要があり、直接配列を渡すことができないからです。

そこでapplyを使ってMath.max.apply(null, numbers)のようにすると、イメージ的にはapplyメソッドがnumbers配列内の要素を一つずつ取り出してMath.maxの引数に渡してあげていると考えることができます。

つまりMath.max.apply(null, [4, 9, 1, 6, 8, 3])Math.max(4, 9, 1, 6, 8, 3)になると考えることができます。 (Math.max(...numbers)でできるやん!ってことはさておき...)

以上をまとめると、applyの使い方として

  • 関数内のthisの参照先を変えることができる
  • ある配列内の要素を for 文みたいにいい感じに 1 個ずつ取り出して別の関数の引数として渡すことができる

参考:
MDN - Function.prototype.apply()

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