この文書は翻訳中です。他国語のままの部分などがあるのはその為です。
是非お気軽に MDN に登録して翻訳に参加し、私たちの手助けをして下さい!
概要
関数内での this キーワードの値を明示的に指定して関数を呼び出します。 呼び出し先の関数に引数として渡される値は、配列に格納して call メソッドの第 2 引数で指定します。
call() メソッドに似ていますが、呼び出し先関数に渡す引数の指定方法が異なります。 call() メソッドは、第 2 引数以降の引数をそのまま呼び出し先関数に渡す引数とします。| Function のメソッド | |
|---|---|
| 実装されたバージョン | JavaScript 1.3 |
| ECMAScript エディション | ECMA-262 3rd Edition |
構文
fun.apply(thisArg[, argsArray])
引数
-
thisArg -
呼び出し先関数
funの中でthisパラメータとして使用される値です。 実際にこの値が関数の中でthisの値として使用されるとは限りません: もし、関数が non-strict mode のコードで、nullかundefinedが指定された場合はthisの値は global object になります。 また、プリミティブ値はボクシングされます。 -
argsArray -
関数
funの引数として渡される値を格納した配列のようなオブジェクト、もしくはnullかundefined。nullかundefinedの場合は、funには引数が渡されません。
JavaScript 1.8.5 における注記
JavaScript 1.8.5 (Firefox 4) から、このメソッドは ECMAScript 5 仕様に従うようになりました。 つまり、これまで第 2 引数には配列を渡す必要がありましたが、配列のようなオブジェクトでも良いようになりました。この変更についての詳細は bug 562448 を参照してください。
説明
関数を呼び出すときに、 this を別のオブジェクトに割り当てることができます。this は呼び出しているオブジェクト、現在のオブジェクトを参照します。apply を使うことで、一度メソッドを書いたあと、他のオブジェクトへ継承させるためにメソッドを書きなおさなくてもよくなります。
apply は、引数にとることのできる型を除いて call ととてもく似ています。ひとつの配列を名前をつけたパラメータの代わりに使うことができます。 apply には、 fun.apply(this, ['eat', 'bananas']) のような配列のリテラルや、 fun.apply(this, new Array('eat', 'bananas')) のような配列オブジェクトを使うことができます。
You can also use arguments for the argsArray parameter. arguments is a local variable of a function. It can be used for all unspecified arguments of the called object. Thus, you do not have to know the arguments of the called object when you use the apply method. You can use arguments to pass all the arguments to the called object. The called object is then responsible for handling the arguments.
ECMAScript 5から、配列のようなオブジェクトも渡すことができるようになりました。 これは、length というプロパティと、0から length までの整数のプロパティを持つオブジェクトのことです。例を挙げると、 As an example you can now use a NodeList or a own custom object like {'length': 2, '0': 'eat', '1': 'bananas'}.
例
applyを用いたコンストラクタチェーン
applyを使うことで、Javaのようなコンストラクタチェーンを実現することができます。以下の例では、constructというメソッドをグローバルなFunctionに作ります。このメソッドを使うことで、引数リストの代わりに配列のようなオブジェクトをコンストラクタに渡すことができるようにします。
Function.prototype.construct = function (aArgs) {
var fConstructor = this, fNewConstr = function () { fConstructor.apply(this, aArgs); };
fNewConstr.prototype = fConstructor.prototype;
return new fNewConstr();
};
次に使用例を示します。
function MyConstructor () {
for (var nProp = 0; nProp < arguments.length; nProp++) {
this["property" + nProp] = arguments[nProp];
}
}
var myArray = [4, "Hello world!", false];
var myInstance = MyConstructor.construct(myArray);
alert(myInstance.property1); // alerts "Hello world!"
alert(myInstance instanceof MyConstructor); // alerts "true"
alert(myInstance.constructor); // alerts "MyConstructor"
Function.construct method will not work with some native constructors (like Date, for example). In these cases you have to use the Function.bind method (for example, imagine to have an array like the following, to be used with Date constructor: [2012, 11, 4]; in this case you have to write something like: new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))() – anyhow this is not the best way to do things and probably should not be used in any production environment).apply and built-in functions
Clever usage of apply allows you to use built-ins functions for some tasks that otherwise probably would have been written by looping over the array values. As an example here we are going to use Math.max/Math.min to find out the maximum/minimum value in an array.
/* min/max number in an array */
var numbers = [5, 6, 2, 3, 7];
/* using Math.min/Math.max apply */
var max = Math.max.apply(null, numbers); /* This about equal to Math.max(numbers[0], ...) or Math.max(5, 6, ..) */
var min = Math.min.apply(null, numbers);
/* vs. simple loop based algorithm */
max = -Infinity, min = +Infinity;
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] > max)
max = numbers[i];
if (numbers[i] < min)
min = numbers[i];
}
But beware: in using apply this way, you run the risk of exceeding the JavaScript engine's argument length limit. The consequences of applying a function with too many arguments (think more than tens of thousands of arguments) vary across engines (JavaScriptCore has hard-coded argument limit of 65536), because the limit (indeed even the nature of any excessively-large-stack behavior) is unspecified. Some engines will throw an exception. More perniciously, others will arbitrarily limit the number of arguments actually passed to the applied function. (To illustrate this latter case: if such an engine had a limit of four arguments [actual limits are of course significantly higher], it would be as if the arguments 5, 6, 2, 3 had been passed to apply in the examples above, rather than the full array.) If your value array might grow into the tens of thousands, use a hybrid strategy: apply your function to chunks of the array at a time:
function minOfArray(arr) {
var min = Infinity;
var QUANTUM = 32768;
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
min = Math.min(submin, min);
}
return min;
}
var min = minOfArray([5, 6, 2, 3, 7]);
Mozilla Developer Network