callとapplyの違いは何ですか?

関数を呼び出すのにcallapplyの違いは何ですか?

var func = function() {
  alert('hello!');
};

func.apply();vsfunc.call();` です。

前述の 2 つのメソッドにはパフォーマンスの違いがありますか?どのような場合に apply よりも call を使用するのがベストで、その逆もまた然りですか?

ソリューション

違いは、applyでは `arguments を配列にして関数を呼び出すことができ、callではパラメータを明示的に列挙する必要があることです。便利なニーモニックは、_"Aarray、Ccomma."_です。

MDN'の[apply][1]とcallのドキュメントを参照してください。

擬似的な構文です。

theFunction.apply(valueForThis, arrayOfArgs) です。

theFunction.call(valueForThis, arg1, arg2, ...)

また、ES6では、call関数で使用するために配列をspreadすることも可能で、その互換性はこちらで確認できます。

サンプルコードです。

function theFunction(name, profession) {
    console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // used with the spread operator

[1]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

解説 (12)

K.Scott Allenがこの件についてa nice writeupを書いています。

基本的には、関数の引数をどのように扱うかという点で違いがあります。

apply()メソッドはcall()と同じですが、 apply()は2番目のパラメータとして配列を必要とします。この配列は、対象となるメソッドの引数を表します。

というわけです。

// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
解説 (2)

各関数をいつ使用するかという部分についてお答えしますと、渡す引数の数がわからない場合や、引数がすでに配列や配列のようなオブジェクト(自分の引数を転送するためのargumentsオブジェクトのようなもの)に入っている場合には、applyを使用します。それ以外の場合は、引数を配列で包む必要がないので、callを使います。

f.call(thisObject, a, b, c); // Fixed number of arguments

f.apply(thisObject, arguments); // Forward this function's arguments

var args = [];
while (...) {
    args.push(some_value());
}
f.apply(thisObject, args); // Unknown number of arguments

引数を渡さない場合(あなたの例のように)、私はcallを好みます。なぜなら私は関数を呼び出しているからです。apply`は、(存在しない)引数に関数を適用していることを意味します。

性能的な違いはないと思いますが、applyを使って引数を配列で囲む場合は別です(例:f.call(thisObject, a, b, c)の代わりにf.apply(thisObject, [a, b, c]))。テストはしていないので、違いがあるかもしれませんが、非常にブラウザに依存するでしょう。まだ引数が配列になっていない場合は call の方が速く、配列になっている場合は apply の方が速いと思われます。

解説 (0)