--- title: Function.prototype.apply() slug: Web/JavaScript/Reference/Global_Objects/Function/apply translation_of: Web/JavaScript/Reference/Global_Objects/Function/apply original_slug: Web/JavaScript/Referencje/Obiekty/Function/apply ---
{{JSRef}}

Metoda apply() wywołuje daną funkcję podstawiając daną wartość this i argumenty przedstawione w postaci tablicy (lub obiektu tablicopodobnego (array-like object)).

Notka: Składnia tej funkcji jest niemal identyczna do {{jsxref("Function.call", "call()")}}, podstawową różnicą jest to, iż call() przyjmuje listę argumentów, podczas gdy apply() akceptuje pojedynczą tablicę argumentów.

Składnia

function.apply(thisArg, [argsArray])

Parametry

thisArg
Optional. The value of this provided for the call to func. Note that this may not be the actual value seen by the method: if the method is a function in {{jsxref("Strict_mode", "non-strict mode", "", 1)}} code, {{jsxref("null")}} and {{jsxref("undefined")}} will be replaced with the global object, and primitive values will be boxed.
argsArray
Optional. An array-like object, specifying the arguments with which fun should be called, or {{jsxref("null")}} or {{jsxref("undefined")}} if no arguments should be provided to the function. Starting with ECMAScript 5 these arguments can be a generic array-like object instead of an array. See below for {{anch("Browser_compatibility", "browser compatibility")}} information.

Zwracana wartość

Wynik wywoływanej funkcji z określoną wartością this i argumentami.

Opis

Można przypisać inny obiekt this podczas wywoływania istniejącej funkcji. this odnosi się do bieżącego obiektu, obiektu wywołującego. Z apply można napisać metodę raz, a następnie dziedziczyć w innym obiekcie, bez konieczności przepisywania metody dla nowego obiektu.

apply jest bardzo podobne do {{jsxref("Function.call", "call()")}}, z wyjątkiem typu danych argumentów, które wspiera. Można używać tablicy argumentów zamiast zestawu argumentów (parametrów). Z metodą apply, możesz używać tablic w sensie dosłownym, na przykład func.apply(this, ['eat', 'bananas']), lub obiektów typu {{jsxref("Array")}}, na przykład, func.apply(this, new Array('eat', 'bananas')).

Można używać również {{jsxref("Funkcje/arguments", "arguments")}} dla parametru argsArray. arguments jest zmienną lokalną dostępną wewnątrz każdej funkcji. Można to zastosować do wszystkich nieokreślonych argumentów wywoływanego obiektu. Tak więc nie trzeba znać argumentów wywoływanego obiektu przy użyciu metody apply Możesz użyć arguments, aby przekazać wszystkie argumenty do wywoływanego obiektu. Wywołany obiekt jest odpowiedzialny za obsługę otrzymanych argumentów.

Od ECMAScript 5th Edition możliwe jest również używanie wszelkiego rodzaju obiektów „tablicopodobnych” (array-like), co w praktyce oznacza, że obiekt taki musi mieć własność length i całkowite własności (indeksy) w zakresie (0..length-1). Przykładowo możesz użyć {{domxref("NodeList")}} lub własnego oiektu jak np. { 'length': 2, '0': 'eat', '1': 'bananas' }.

Większość przeglądarek, w tym Chrome 14 i Internet Explorer 9, w dalszym ciągu nie akceptuje obiektów tablicopodobnych i będzie wyrzucać wyjątek.

Przykłady

Użycie apply do dodania tablicy do innej tablicy

Możemy użyć metody push do dodania elementu do tablicy. I, jako że push przyjmuje zmienną liczbę argumentów, możemy również dodać wiele elementów naraz – ale jeśli faktycznie przekażemy tablicę do funkcji push, wówczas rzeczywiście doda ona tablicę jako pojedynczy element, zamiast dodać jej elementy, więc skończymy z tablicą wewnątrz tablicy. Co jeśli to nie jest to, co chcieliśmy osiągnąć? concat ma zachowanie takie, jakiego oczekiwalibyśmy w tym przypadku, jednak funkcja ta nie dodaje w rzeczywistości tablicy do istniejącej tablicy, ale tworzy i zwraca nową. Ale chcieliśmy zmodyfikować naszą istniejącą tablicę… Więc co teraz? Napisać pętlę? No chyba nie?

apply przychodzi na ratunek!

var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]

 

Using 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]);

 

Using apply to chain constructors

 

You can use apply to chain {{jsxref("Operators/new", "constructors", "", 1)}} for an object, similar to Java. In the following example we will create a global {{jsxref("Function")}} method called construct, which will enable you to use an array-like object with a constructor instead of an arguments list.

Function.prototype.construct = function(aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};

Note: The Object.create() method used above is relatively new. For alternative methods, please consider one of the following approaches:

Using {{jsxref("Object/__proto__", "Object.__proto__")}}:

Function.prototype.construct = function (aArgs) {
  var oNew = {};
  oNew.__proto__ = this.prototype;
  this.apply(oNew, aArgs);
  return oNew;
};

Using closures:

Function.prototype.construct = function(aArgs) {
  var fConstructor = this, fNewConstr = function() {
    fConstructor.apply(this, aArgs);
  };
  fNewConstr.prototype = fConstructor.prototype;
  return new fNewConstr();
};

Using the {{jsxref("Function")}} constructor:

Function.prototype.construct = function (aArgs) {
  var fNewConstr = new Function("");
  fNewConstr.prototype = this.prototype;
  var oNew = new fNewConstr();
  this.apply(oNew, aArgs);
  return oNew;
};

Example usage:

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);

console.log(myInstance.property1);                // logs 'Hello world!'
console.log(myInstance instanceof MyConstructor); // logs 'true'
console.log(myInstance.constructor);              // logs 'MyConstructor'

Note: This non-native Function.construct method will not work with some native constructors; like {{jsxref("Date")}}, for example. In these cases you have to use the {{jsxref("Function.prototype.bind")}} method. For example, imagine having an array like the following, to be used with {{jsxref("Global_Objects/Date", "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])))(). This is not the best way to do things, and probably not to be used in any production environment.

Specyfikacje

Specification Status Comment
{{SpecName('ES3')}} {{Spec2('ES3')}} Initial definition. Implemented in JavaScript 1.3.
{{SpecName('ES5.1', '#sec-15.3.4.3', 'Function.prototype.apply')}} {{Spec2('ES5.1')}}  
{{SpecName('ES6', '#sec-function.prototype.apply', 'Function.prototype.apply')}} {{Spec2('ES6')}}  
{{SpecName('ESDraft', '#sec-function.prototype.apply', 'Function.prototype.apply')}} {{Spec2('ESDraft')}}  

Zgodność z przeglądarkami

{{CompatibilityTable}}
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}}
ES 5.1 generic array-like object as {{jsxref("Functions/arguments", "arguments")}} {{CompatVersionUnknown}} {{CompatGeckoDesktop("2.0")}} {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}}
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}} {{CompatVersionUnknown}}
ES 5.1 generic array-like object as {{jsxref("Functions/arguments", "arguments")}} {{CompatUnknown}} {{CompatUnknown}} {{CompatGeckoMobile("2.0")}} {{CompatUnknown}} {{CompatUnknown}} {{CompatUnknown}}

Zobacz również