Quelle est la différence entre appeler et postuler?

3105

Quelle est la différence entre l'utilisation callet l' applyinvocation d'une fonction?

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

func.apply(); contre func.call();

Existe-t-il des différences de performances entre les deux méthodes susmentionnées? Quand est-il préférable d'utiliser callplus applyet vice versa?

John Duff
la source
727
Pensez aà appliquer un tableau d'arguments et cà appeler des colonnes d'arguments.
Larry Battle
176
@LarryBattle Je fais presque la même chose, mais je pense qu'un in s'applique au tableau et c un appel à la virgule (c'est-à-dire des arguments séparés par des virgules).
Samih
3
Je suis d'accord, c'est stupide. Ce qui est ennuyeux, c'est que cette question est posée d'une manière ou d'une autre pendant les entretiens, car un connard influent a ajouté la question à sa liste de questions importantes sur js.
Ringo
6
Vous appliquez un emploi une fois (un argument), vous [téléphone] appel gens plusieurs fois (plusieurs arguments). Alternative: il y a [trop?] De nombreux jeux Call of Duty.
Gras Double
1
Lorsque l'intention est d'invoquer une fonction variadique avec une liste de valeurs d'argument indépendamment de "cette" valeur, utilisez alors l'opérateur d'étalement ES6, par exemple fn(...input)lorsque input est un tableau. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Gajus

Réponses:

3649

La différence est que applyvous pouvez invoquer la fonction avec argumentsun tableau; callnécessite que les paramètres soient répertoriés explicitement. Un mnémonique utile est " A pour un rray et C pour c omma."

Voir la documentation de MDN sur l' application et l' appel .

Pseudo syntaxe:

theFunction.apply(valueForThis, arrayOfArgs)

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

Il y a aussi, à partir d'ES6, la possibilité d' spreadutiliser le tableau pour la callfonction, vous pouvez voir les compatibilités ici .

Exemple de code:

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

flatline
la source
25
Une chose à ajouter est que les arguments doivent être un tableau numérique ([]). Les tableaux associatifs ({}) ne fonctionneront pas.
Kevin Schroeder
326
@KevinSchroeder: Dans le javascript, []est appelé un tableau , {}est appelé un objet .
Martijn
89
J'avais souvent l'habitude d'oublier ce qui prend un tableau et qui attend de vous que vous listiez les arguments. Une technique que j'ai utilisée pour m'en souvenir est que si la première lettre de la méthode commence par un, alors il faut un tableau, c'est -à- dire un tableau pply
aziz punjani
16
@SAM L'utilisation d'un appel au lieu d'un appel de fonction normal n'a de sens que si vous devez modifier la valeur de ceci pour l'appel de fonction. Un exemple (qui convertit un objet-arguments de fonctions en un tableau): Array.prototype.slice.call(arguments)ou [].slice.call(arguments). appliquer a du sens si vous avez les arguments dans un tableau, par exemple dans une fonction qui appelle une autre fonction avec (presque) les mêmes paramètres. Recommandation Utilisez un appel de fonction normal funcname(arg1)si cela fait ce dont vous avez besoin, enregistrez l' appel et postulez pour les occasions spéciales où vous en avez vraiment besoin.
certains
4
@KunalSingh Both callet applyprend deux paramètres. Le premier argument de la apply' and fonction call` doit être l'objet propriétaire et le deuxième paramètre sera respectivement des paramètres séparés par des tableaux ou des virgules. Si vous passez nullou undefinedcomme premier argument, alors en mode non strict, ils sont remplacés par un objet global, c'estwindow
AJ Qarshi
229

K. Scott Allen a un bon résumé sur la question.

Fondamentalement, ils diffèrent sur la façon dont ils gèrent les arguments de fonction.

La méthode apply () est identique à call (), sauf que apply () requiert un tableau comme deuxième paramètre. Le tableau représente les arguments de la méthode cible. "

Donc:

// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
notnoop
la source
42
le deuxième paramètre de apply () et call () est facultatif, pas obligatoire.
kiwi en colère
34
Le premier paramètre n'est pas non plus requis.
Ikrom
@Ikrom, le premier paramètre n'est pas requis callmais obligatoire pour apply
iamcastelli
160

Pour répondre à la partie sur le moment où utiliser chaque fonction, utilisez applysi vous ne connaissez pas le nombre d'arguments que vous passerez, ou s'ils sont déjà dans un tableau ou un objet semblable à un tableau (comme l' argumentsobjet pour transmettre vos propres arguments. Utilisez-le callautrement, car il n'est pas nécessaire d'envelopper les arguments dans un tableau.

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

Quand je ne passe aucun argument (comme votre exemple), je préfère calldepuis que je suis d' appeler la fonction. applyimpliquerait que vous appliquez la fonction aux arguments (inexistants).

Il ne devrait pas y avoir de différences de performances, sauf peut-être si vous utilisez applyet encapsulez les arguments dans un tableau (par exemple f.apply(thisObject, [a, b, c])au lieu de f.call(thisObject, a, b, c)). Je ne l'ai pas testé, il pourrait donc y avoir des différences, mais ce serait très spécifique au navigateur. C'est probablement callplus rapide si vous n'avez pas déjà les arguments dans un tableau et applyplus rapide si vous en avez.

Matthew Crumley
la source
111

Voici un bon mnémonique. A pply utilise A rrays et A lways prend un ou deux arguments. Lorsque vous utilisez C tout ce que vous avez à C ontant le nombre d'arguments.

Joe
la source
2
Mnémonique utile là !. Je changerai «un ou deux arguments» pour dire «un maximum de deux arguments» car ni le premier ni le deuxième paramètre de applyn'est requis. Je ne sais pas pourquoi on appellera applyou callsans paramètre. On dirait que quelqu'un essaie de savoir pourquoi ici stackoverflow.com/questions/15903782/…
dantheta
92

Bien que ce soit un vieux sujet, je voulais juste souligner que .call est légèrement plus rapide que .apply. Je ne peux pas vous dire exactement pourquoi.

Voir jsPerf, http://jsperf.com/test-call-vs-apply/3


[ UPDATE!]

Douglas Crockford mentionne brièvement la différence entre les deux, ce qui peut aider à expliquer la différence de performance ... http://youtu.be/ya4UHuXNygM?t=15m52s

Appliquer prend un tableau d'arguments, tandis que Call prend zéro ou plusieurs paramètres individuels! Ah hah!

.apply(this, [...])

.call(this, param1, param2, param3, param4...)

kmatheny
la source
Cela dépend de ce que la fonction fait avec les paramètres / tableau, si elle n'a pas besoin de traiter le tableau, cela prend-il moins de temps?
Eric Hodonsky
12
Fait intéressant, même sans le tableau, l'appel est encore beaucoup plus rapide. jsperf.com/applyvscallvsfn2
Josh Mc
@JoshMc Ce serait très spécifique au navigateur. Dans IE 11, je reçois une demande allant deux fois plus vite que l'appel.
Vincent McNabb
1
1. La création d'un nouveau tableau signifie que le garbage collector devra le nettoyer à un moment donné. 2. L'accès aux éléments du tableau à l'aide du déréférencement est moins efficace que l'accès direct à une variable (paramètre). (Je crois que c'est ce que kmatheny voulait dire par "analyse", qui est en fait quelque chose de tout à fait différent.) Mais aucun de mes arguments n'explique le jsperf. Cela doit être lié à l'implémentation par le moteur des deux fonctions, par exemple peut-être qu'elles créent de toute façon un tableau vide, si aucune n'a été transmise.
joeytwiddle
Merci d'avoir partagé le test et la vidéo
Gary
76

Suit un extrait de Closure: The Definitive Guide de Michael Bolin . Cela peut sembler un peu long, mais il est saturé de beaucoup de perspicacité. Extrait de "Annexe B. Concepts JavaScript fréquemment mal compris":


À quoi fait thisréférence lorsqu'une fonction est appelée

Lors de l'appel d'une fonction du formulaire foo.bar.baz(), l'objet foo.barest appelé récepteur. Lorsque la fonction est appelée, c'est le récepteur qui est utilisé comme valeur pour this:

var obj = {};
obj.value = 10;
/** @param {...number} additionalValues */
obj.addValues = function(additionalValues) {
  for (var i = 0; i < arguments.length; i++) {
    this.value += arguments[i];
  }
  return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);

S'il n'y a pas de récepteur explicite lorsqu'une fonction est appelée, alors l'objet global devient le récepteur. Comme expliqué dans "goog.global" à la page 47, la fenêtre est l'objet global lorsque JavaScript est exécuté dans un navigateur Web. Cela conduit à un comportement surprenant:

var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN

Même si obj.addValueset freportez - vous à la même fonction, ils se comportent différemment lorsqu'il est appelé parce que la valeur du récepteur est différent dans chaque appel. Pour cette raison, lors de l'appel d'une fonction qui fait référence this, il est important de s'assurer qu'elle thisaura la bonne valeur lors de son appel. Pour être clair, s'ils thisn'étaient pas référencés dans le corps de la fonction, le comportement de f(20)et obj.addValues(20)serait le même.

Comme les fonctions sont des objets de première classe en JavaScript, elles peuvent avoir leurs propres méthodes. Toutes les fonctions ont des méthodes call()et apply()qui permettent de redéfinir le récepteur (c'est-à-dire l'objet auquel il se thisréfère) lors de l'appel de la fonction. Les signatures de méthode sont les suivantes:

/**
* @param {*=} receiver to substitute for 'this'
* @param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* @param {*=} receiver to substitute for 'this'
* @param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;

Notez que la seule différence entre call()et apply()est que call()reçoit les paramètres de la fonction sous forme d'arguments individuels, alors qu'il les apply()reçoit sous la forme d'un tableau unique:

// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);

Les appels suivants sont équivalents fet obj.addValuesfont référence à la même fonction:

obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);

Cependant, puisque call()ni apply()n'utilise la valeur de son propre récepteur pour remplacer l'argument récepteur lorsqu'il n'est pas spécifié, les éléments suivants ne fonctionneront pas:

// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);

La valeur de thisne peut jamais être nullou undefinedlorsqu'une fonction est appelée. Lorsque nullou undefinedest fourni en tant que récepteur à call()ou apply(), l'objet global est utilisé à la place comme valeur pour le récepteur. Par conséquent, le code précédent a le même effet secondaire indésirable que l'ajout d'une propriété nommée valueà l'objet global.

Il peut être utile de considérer une fonction comme n'ayant aucune connaissance de la variable à laquelle elle est affectée. Cela permet de renforcer l'idée que la valeur de ceci sera liée lorsque la fonction est appelée plutôt que lorsqu'elle est définie.


Fin de l'extrait.

Dominykas Mostauskis
la source
Juste pour noter le fait, ce additionalValuesn'est pas référencé à l'intérieur du obj.addValuescorps
Viktor Stolbin
Je sais que vous répondiez à la question, mais vous aimeriez ajouter: vous auriez pu utiliser bind lors de la définition de f. var f = obj.addValues;devient var f = obj.addValues.bind(obj) et maintenant f (20) fonctionnerait sans avoir à utiliser appel ou appliquer à chaque fois.
jhliberty
Je sais que vous ne l'avez pas écrit, mais vous avez souligné le texte et les exemples du livre comme pertinents, et je vous en suis très reconnaissant. Ils ont été très utiles.
Fralcon
34

Il est parfois utile qu'un objet emprunte la fonction d'un autre objet, ce qui signifie que l'objet emprunteur exécute simplement la fonction prêtée comme si c'était la sienne.

Un petit exemple de code:

var friend = {
    car: false,
    lendCar: function ( canLend ){
      this.car = canLend;
 }

}; 

var me = {
    car: false,
    gotCar: function(){
      return this.car === true;
  }
};

console.log(me.gotCar()); // false

friend.lendCar.call(me, true); 

console.log(me.gotCar()); // true

friend.lendCar.apply(me, [false]);

console.log(me.gotCar()); // false

Ces méthodes sont très utiles pour donner aux objets des fonctionnalités temporaires.

tjacks3
la source
1
Pour les personnes qui veulent savoir comment console.logconsulter: Qu'est-ce que console.log et comment l'utiliser?
Michel Ayres
25

Un autre exemple avec Call, Apply et Bind. La différence entre appeler et appliquer est évidente, mais Bind fonctionne comme ceci:

  1. Bind renvoie une instance d'une fonction qui peut être exécutée
  2. Le premier paramètre est « ceci »
  3. Le deuxième paramètre est une liste d'arguments séparés par des virgules (comme Call )

}

function Person(name) {
    this.name = name; 
}
Person.prototype.getName = function(a,b) { 
     return this.name + " " + a + " " + b; 
}

var reader = new Person('John Smith');

reader.getName = function() {
   // Apply and Call executes the function and returns value

   // Also notice the different ways of extracting 'getName' prototype
   var baseName = Object.getPrototypeOf(this).getName.apply(this,["is a", "boy"]);
   console.log("Apply: " + baseName);

   var baseName = Object.getPrototypeOf(reader).getName.call(this, "is a", "boy"); 
   console.log("Call: " + baseName);

   // Bind returns function which can be invoked
   var baseName = Person.prototype.getName.bind(this, "is a", "boy"); 
   console.log("Bind: " + baseName());
}

reader.getName();
/* Output
Apply: John Smith is a boy
Call: John Smith is a boy
Bind: John Smith is a boy
*/
Mahesh
la source
23

Je voudrais montrer un exemple, où l'argument 'valueForThis' est utilisé:

Array.prototype.push = function(element) {
   /*
   Native code*, that uses 'this'       
   this.put(element);
   */
}
var array = [];
array.push(1);
array.push.apply(array,[2,3]);
Array.prototype.push.apply(array,[4,5]);
array.push.call(array,6,7);
Array.prototype.push.call(array,8,9);
//[1, 2, 3, 4, 5, 6, 7, 8, 9] 

** détails: http://es5.github.io/#x15.4.4.7 *


la source
20

Call () prend des arguments séparés par des virgules, ex:

.call(scope, arg1, arg2, arg3)

et apply () prend un tableau d'arguments, ex:

.apply(scope, [arg1, arg2, arg3])

voici quelques exemples d'utilisation supplémentaires: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/

Mark Karwowski
la source
`// call () === arguments séparés par des virgules (arguments-list) .call (this, args1, args2, args3, ...) // apply () === tableau d'arguments (array-items). appliquer (ceci, [arr0, arr1, arr2, ...]) `
xgqfrms
19

À partir des documents MDN sur Function.prototype.apply () :

La méthode apply () appelle une fonction avec une thisvaleur donnée et des arguments fournis sous la forme d'un tableau (ou d'un objet de type tableau).

Syntaxe

fun.apply(thisArg, [argsArray])

A partir des documents MDN sur Function.prototype.call () :

La méthode call () appelle une fonction avec une thisvaleur donnée et des arguments fournis individuellement.

Syntaxe

fun.call(thisArg[, arg1[, arg2[, ...]]])

De Function.apply et Function.call en JavaScript :

La méthode apply () est identique à call (), sauf que apply () requiert un tableau comme deuxième paramètre. Le tableau représente les arguments de la méthode cible.


Exemple de code:

var doSomething = function() {
    var arr = [];
    for(i in arguments) {
        if(typeof this[arguments[i]] !== 'undefined') {
            arr.push(this[arguments[i]]);
        }
    }
    return arr;
}

var output = function(position, obj) {
    document.body.innerHTML += '<h3>output ' + position + '</h3>' + JSON.stringify(obj) + '\n<br>\n<br><hr>';
}

output(1, doSomething(
    'one',
    'two',
    'two',
    'one'
));

output(2, doSomething.apply({one : 'Steven', two : 'Jane'}, [
    'one',
    'two',
    'two',
    'one'
]));

output(3, doSomething.call({one : 'Steven', two : 'Jane'},
    'one',
    'two',
    'two',
    'one'
));

Voir aussi ce violon .

John Slegers
la source
10

Voici un petit article, j'ai écrit à ce sujet:

http://sizeableidea.com/call-versus-apply-javascript/

var obj1 = { which : "obj1" },
obj2 = { which : "obj2" };

function execute(arg1, arg2){
    console.log(this.which, arg1, arg2);
}

//using call
execute.call(obj1, "dan", "stanhope");
//output: obj1 dan stanhope

//using apply
execute.apply(obj2, ["dan", "stanhope"]);
//output: obj2 dan stanhope

//using old school
execute("dan", "stanhope");
//output: undefined "dan" "stanhope"
Dan
la source
en voici un autre: blog.i-evaluation.com/2012/08/15/javascript-call-and-apply mais en gros c'est vrai: .call (scope, arg1, arg2, arg3)
Mark Karwowski
7

La différence est que call()prend les arguments de fonction séparément et apply()prend les arguments de fonction dans un tableau.

Sanjib Debnath
la source
6

Nous pouvons différencier l'appel et appliquer des méthodes comme ci-dessous

CALL: Une fonction avec argument fournit individuellement. Si vous connaissez les arguments à passer ou qu'il n'y a aucun argument à passer, vous pouvez utiliser call.

APPLY: appeler une fonction avec l'argument fourni sous forme de tableau. Vous pouvez utiliser apply si vous ne savez pas combien d'arguments vont passer à la fonction.

Il y a un avantage à utiliser apply par rapport à l'appel, nous n'avons pas besoin de changer le nombre d'arguments seulement nous pouvons changer un tableau qui est passé.

Il n'y a pas de grande différence de performances. Mais nous pouvons dire que l'appel est un peu plus rapide que comparer à appliquer, car un tableau doit être évalué dans la méthode apply.

Praveen D
la source
5

La différence entre ces méthodes et la manière dont vous souhaitez transmettre les paramètres.

«A pour tableau et C pour virgule» est un mnémonique pratique.

venkat7668
la source
11
Que propose cette réponse qui n'est pas déjà bien fournie dans les autres réponses?
Kyll
5

Appeler et appliquer les deux sont utilisés pour forcer la thisvaleur lorsqu'une fonction est exécutée. La seule différence est que callprend les n+1arguments où 1 est thiset 'n' arguments. applyprend seulement deux arguments, l'un est thisl'autre est un tableau d'arguments.

L'avantage que je vois applyplus callest que nous pouvons facilement déléguer un appel de fonction à une autre fonction sans trop d'effort;

function sayHello() {
  console.log(this, arguments);
}

function hello() {
  sayHello.apply(this, arguments);
}

var obj = {name: 'my name'}
hello.call(obj, 'some', 'arguments');

Observons la facilité avec laquelle nous avons délégué helloà l' sayHelloutilisation apply, mais callcela est très difficile à réaliser.

Raghavendra
la source
4

Même si callet à applyatteindre la même chose, je pense qu'il y a au moins un endroit où vous ne pouvez pas utiliser, callmais ne pouvez utiliser apply. C'est à ce moment que vous souhaitez prendre en charge l'héritage et appeler le constructeur.

Voici une fonction qui vous permet de créer des classes qui prennent également en charge la création de classes en étendant d'autres classes.

function makeClass( properties ) {
    var ctor = properties['constructor'] || function(){}
    var Super = properties['extends'];
    var Class = function () {
                 // Here 'call' cannot work, only 'apply' can!!!
                 if(Super)
                    Super.apply(this,arguments);  
                 ctor.apply(this,arguments);
                }
     if(Super){
        Class.prototype = Object.create( Super.prototype );
        Class.prototype.constructor = Class;
     }
     Object.keys(properties).forEach( function(prop) {
           if(prop!=='constructor' && prop!=='extends')
            Class.prototype[prop] = properties[prop];
     });
   return Class; 
}

//Usage
var Car = makeClass({
             constructor: function(name){
                         this.name=name;
                        },
             yourName: function() {
                     return this.name;
                   }
          });
//We have a Car class now
 var carInstance=new Car('Fiat');
carInstance.youName();// ReturnsFiat

var SuperCar = makeClass({
               constructor: function(ignore,power){
                     this.power=power;
                  },
               extends:Car,
               yourPower: function() {
                    return this.power;
                  }
              });
//We have a SuperCar class now, which is subclass of Car
var superCar=new SuperCar('BMW xy',2.6);
superCar.yourName();//Returns BMW xy
superCar.yourPower();// Returns 2.6
Dhana Krishnasamy
la source
Je crois que l'appel fonctionnerait là-bas avec l'opérateur d'étalement comme décrit dans la réponse sélectionnée. A moins que je manque quelque chose.
jhliberty
4

Sommaire:

Les deux call()et apply()sont des méthodes qui se trouvent sur Function.prototype. Ils sont donc disponibles sur chaque objet fonction via la chaîne de prototypes. Les deux call()et apply()peuvent exécuter une fonction avec une valeur spécifiée de this.

La principale différence entre call()et apply()est la façon dont vous devez lui transmettre des arguments. Dans les deux call(), apply()vous passez comme premier argument l'objet sous lequel vous souhaitez être la valeur this. Les autres arguments diffèrent de la manière suivante:

  • Avec call()vous devez mettre les arguments normalement (à partir du deuxième argument)
  • Avec apply()vous devez passer dans un tableau d'arguments.

Exemple:

let obj = {
  val1: 5,
  val2: 10
}

const summation = function (val3, val4) {
  return  this.val1 + this.val2 + val3 + val4;
}

console.log(summation.apply(obj, [2 ,3]));
// first we assign we value of this in the first arg
// with apply we have to pass in an array


console.log(summation.call(obj, 2, 3));
// with call we can pass in each arg individually

Pourquoi aurais-je besoin d'utiliser ces fonctions?

La thisvaleur peut parfois être délicate en javascript. La valeur de thisdéterminé lorsqu'une fonction est exécutée et non lorsqu'une fonction est définie. Si notre fonction dépend d'une thisliaison droite, nous pouvons utiliser call()et apply()appliquer ce comportement. Par exemple:

var name = 'unwantedGlobalName';

const obj =  {
  name: 'Willem',
  sayName () { console.log(this.name);}
}


let copiedMethod = obj.sayName;
// we store the function in the copiedmethod variable



copiedMethod();
// this is now window, unwantedGlobalName gets logged

copiedMethod.call(obj);
// we enforce this to be obj, Willem gets logged

Willem van der Veen
la source
4

La principale différence est qu'en utilisant call, nous pouvons changer la portée et passer des arguments comme d'habitude, mais apply vous permet de l'appeler en utilisant des arguments comme un tableau (passez-les comme un tableau). Mais en termes de ce qu'ils doivent faire dans votre code, ils sont assez similaires.

Alors que la syntaxe de cette fonction est presque identique à celle de apply (), la différence fondamentale est que call () accepte une liste d'arguments, tandis que apply () accepte un seul tableau d'arguments.

Donc, comme vous le voyez, il n'y a pas de grande différence, mais il y a quand même des cas où nous préférons utiliser call () ou apply (). Par exemple, regardez le code ci-dessous, qui recherche le plus petit et le plus grand nombre dans un tableau à partir de MDN, en utilisant la méthode apply:

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

Donc, la principale différence est juste la façon dont nous passons les arguments:

Appel:

function.call(thisArg, arg1, arg2, ...);

Appliquer:

function.apply(thisArg, [argsArray]);
Alireza
la source
2

Permettez-moi d'ajouter un petit détail à cela.

ces deux appels sont presque équivalents:

func.call(context, ...args); // pass an array as list with spread operator

func.apply(context, args);   // is same as using apply

Il n'y a qu'une différence mineure:

  • L' spreadopérateur ... permet de passer itérable args comme liste à appeler.
  • Le applyaccepte uniquement comme tableau args.

Donc, ces appels se complètent. Là où nous attendons un itérable , callça marche, là où nous attendons un tableau , çaapply marche.

Et pour les objets qui sont à la fois itérables et de type tableau , comme un vrai tableau, nous pourrions techniquement utiliser n'importe lequel d'entre eux, mais appliquer sera probablement plus rapide car la plupart des moteurs JavaScript l'optimisent en interne mieux.

Pravin Divraniya
la source