[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Function/apply [Back]  [Original]

Function.prototype.apply() - JavaScript | MDN

Esta pgina foi traduzida do ingls pela comunidade. Saiba mais e junte-se comunidade MDN Web Docs.

View in English Always switch to English

Function.prototype.apply()

Baseline
Widely available

This feature is well established and works across many devices and browser versions. Its been available across browsers since julho de 2015.

O mtodo apply() chama uma funo com um dado valor this e arguments providos como uma array (ou um objeto parecido com um array).

Nota: A sintaxe desta funo quase idntica a essa da call(), a diferena que call() aceita uma lista de argumentos, enquanto apply() aceita um array de argumentos.

In this article

Sintaxe

fun.apply(thisArg, [argsArray])

Parmetros

thisArg

O valor de this fornecido para a chamada de fun. Note que isso talvez no seja o valor real visto pelo mtodo: se um mtodo uma funo em cdigo non-strict mode , null e undefined sero substituidos com o objeto global, e os valores primitivos sero embalados.

argsArray

Um objeto parecido com um array (array-like), especificando os argumentos com os quais fun deve ser chamado, ou null ou undefined se no houverem argumentos que possam ser passados para a funo. Comeando com ECMAScript5 esses argumentos podem ser um objeto genrico array-like ao invs de um array. Veja abaixo a informao de compatibilidade de browsers.

Descrio

Voc pode atribuir um objeto this diferente quando chamar uma funo existente. this refere-se ao objeto atual, o objeto da chamada. Com apply, voc pode escrever um mtodo apenas uma vez e ento herd-lo em outro objeto, sem ter que reescrever o mtodo para o novo objeto.

apply muito parecido com call(), exceto pelo tipo de argumentos que ele suporta. Voc pode usar um array de argumentos em vez de conjunto de parmetros nomeados. Com apply, voc pode usar um array literal, por exemplo, fun.apply(this, ['comer', 'bananas']), ou um objeto Array, por exemplo fun.apply(this, new Array('comer', 'bananas')).

Voc pode tambm usar arguments para o parmetro argsArray. arguments uma varivel local de uma funo. Ele pode ser utilizado para todos os argumentos no especificados do objeto chamado. Assim, voc no tem que saber os argumentos do objeto chamado quando voc usa o mtodo apply. Voc pode usar arguments para passar todos os argumentos para o objeto da chamada. O objeto chamado fica ento responsvel por manipular os argumentos.

Desde a 5a verso do ECMAScript voc pode utilizar qualquer tipo de objeto que parecido com um array (array-like), ento na prtica isso significa que ele vai ter uma propriedade length e propriedades inteiras no intervalor (0... length). Como um exemplo, voc pode agora usar um NodeList ou um objeto personalizado como { 'length': 2, '0': 'comer', '1': 'bananas' }.

Nota: Muitos navegadores, incluindo o Chrome 14 e o Internet Explorer 9, ainda no aceitam objetos parecidos com array e iro lanar uma exceo.

Exemplos

Usando apply para cadeia de construtores

Voc pode usar apply para encadear construtores em um objeto, similar ao Java. No exemplo seguinte ns iremos criar um mtodo de Funo global chamado construct, que far voc capaz de usar um objeto parecido com um array com um construtor ao invs de uma lista de argumentos

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

Nota: O mtodo Object.create() usado acima relativamente novo. Para um mtodo alternativo utilizando closures, por favor considere a seguinte alternativa.

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

Exemplo de uso:

js
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'

Nota: Este mtodo no nativo Function.construct no ir funcionar com alguns construtores nativos (como Date, por exemplo). Nestes casos voc tem que usar o mtodo Function.prototype.bind (por exemplo, imagine ter um array como o seguinte, para ser usado com o construtor Date: [2012, 11, 4]; Neste caso voc tem que escrever algom como: new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))() - de qualquer maneira essa no a melhor forma de fazer as coisas e provavelmente no deve ser utilizado em qualquer ambiente de produo.

Usando apply e funes embutidas

A forma inteligente com que apply utilizado permite voc usar funes nativas que de outra forma provavelmente teriam que ser escritas iterando sobre um array de valores. Aqui, como exemplo, iremos utilizar Math.max/Math.min para achar o valor mximo/mnimo value em um array.

js
/* nmero min/max em um array */
var numbers = [5, 6, 2, 3, 7];

/* utilizando Math.min/Math.max apply */
var max = Math.max.apply(
  null,
  numbers,
); /* Isso est prestes a ser igual a Math.max(numbers[0], ...)
                                            ou Math.max(5, 6, ...) */
var min = Math.min.apply(null, numbers);

/* vs. algoritmo simples baseado em loop */
((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];
  }
}

Mas tome cuidado: ao utilizar o apply desta forma, voc corre o risco de exceder o limite de argumentos do JavaScript. As consequncias de fazer applying em uma funo com muitos argumentos (pense em algo como dezenas de centenas de argumentos) varia de acordo com os engines (JavaScriptCore tem um limite de argumentos de 65536 hard-coded), visto que o limite (na verdade, at mesmo a natureza de qualquer comportamento de um stack excessivamente grande) no especificado. Algumas engines iro jogar uma excesso. De uma forma mais incisiva, outras engines iro limitar de forma arbitrria o nmero de argumentos que podero ser aplicados funo. (Para ilustrar esse ltimo caso: se uma engine dessas tem um limite de quatro argumentos [obviamente, os limites atuais so significativamente maiores], isso seria como se os argumentos 5, 6, 2, 3 do exemplo anterior fossem passados ao apply, ao invs do array completo.) Se o valor do seu array puder crescer casa das dezenas de centenas, use uma estratgia hbrida: aplique suas funes em cada bloco de array por vez:

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

Usando apply em "monkey-patching"

Apply pode ser a melhor forma de monkey-patch uma funo nativa do Firefox, ou de bibliotecas em JS. Dada uma funo someobject.foo, voc poder modificar a funo de uma maneira hackeresca, como por exemplo:

js
var originalfoo = someobject.foo;
someobject.foo = function () {
  // Faa coisas antes de chamar a funo
  console.log(arguments);
  // Chama a funo como se ela estivesse sido chamada normalmente:
  originalfoo.apply(this, arguments);
  // Rode as coisas que vem depois, aqui.
};

Esse mtodo especialmente til quando voc quer fazer debug de eventos, ou interagir com algo que no tem nenhuma API como os diversos eventos .on([event]... events, por exemplo aqueles utilizveis no Devtools Inspector).

Especificaes

Specification
ECMAScript 2027 LanguageSpecification
# sec-function.prototype.apply

Compatibilidade com navegadores

Veja tambm


Web Proxy Viewer  |  New URL  |  Original Page