110 votes

En JavaScript, cela fait-il une différence si j'appelle une fonction avec des parenthèses?

J'ai remarqué une différence lors de l'appel d'une fonction avec des parenthèses vides ou sans parenthèses. Je ne transmets aucun argument à la fonction, je me suis donc demandé quelle serait la différence entre:

 window.onload = initAll();
 

et

 window.onload = initAll;
 

S'il vous plaît expliquer le principe derrière cela. Merci d'avance.

167voto

Pekka 웃 Points 249607

de la fenêtre.onload = initAll();

Cela s'exécute initAll() tout de suite et lui affecte la valeur renvoyée de la fonction d' window.onload. Ce n'est généralement pas ce que vous voulez. initAll() devrait renvoyer une fonction pour ce qui est logique.

de la fenêtre.onload = initAll;

ceci assigne la fonction réelle d' window.onload - c'est possible parce qu'en JavaScript, comme @Felix dit, les fonctions sont des objets de première classe - sans l'exécuter. initAll sera exécuté par la charge de l'événement.

141voto

BenAlabaster Points 20189

Ce Pekka dit est correct, mais je veux dire un peu avec un exemple qui vous permettra d'expliquer à quelqu'un qui ne veut pas comprendre pleinement les pointeurs de fonction ou de délégués.

Je ne vais pas utiliser la fenêtre.onload parce que c'est un peu artificiel à démontrer. Je vais utiliser un simple multiplier la fonction de démonstration à la place:

function Multiply(operator, operand) {
    return operator * operand;
}

Il pourrait tout aussi bien être écrit:

Multiply = function(operator, operand) {
    return operator * operand;
}

Alors que dans le premier exemple, l'implication ne peut pas être évident, le second exemple montre plus clairement que nous sommes en affectant une fonction qui a 2 paramètres à une variable appelée Multiplier, et ce concept de fonctions que des affectations est commun à l'ensemble de javascript. C'est une petite démonstration du fait que les fonctions sont des "citoyens à part entière", c'est qu'ils peuvent être passés exactement comme si nous étions de passage autour de valeurs.

Alors maintenant, à la différence de l'affectation:

var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);

Au moment de la définition de la variable ret, Multipliez est exécuté et la valeur de retour est assignée - ret devient égal à 12.

Permet d'essayer de nouveau d'une manière différente:

var operator = 3;
var operand = 4;
var ret = Multiply;

Maintenant, au point de définir ret, ret devient votre Multiplier la fonction plutôt que le résultat obtenu à partir de votre fonction Multiply. Les appels à ret() sera la cause de votre Multiplier la fonction à exécuter, et vous pouvez les appeler, c'est exactement comme si tu avais appelé à se Multiplier(opérateur, opérande):

var out = ret(3, 4);

est le même que

var out = Multiply(3, 4);

Que vous avez dit que vous allez utiliser ret en tant que délégué pour Multiplier(). Lors de l'appel de ret, nous sommes vraiment se référant à la fonction Multiply.

De retour à la fenêtre de votre.onload. Pensez à ce que:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

initAll = function() {
    return 12;
}

Donc, comme vous pouvez le voir, la fenêtre.onload est une fonction comme une autre fonction, il n'y a rien de spécial à ce sujet. Vous pouvez lui affecter une valeur, de lui attribuer une fonction, la valeur null si vous le désirez, le point est qu'il n'y a plus rien de spécial à propos de la fenêtre.onload qu'il y a sur votre propre fonction. La seule légèrement différent, c'est qu'il est appelé par la fenêtre quand il est chargé. [Disclaimer: je n'ai jamais réellement annulée par la fenêtre de fonctions, donc je ne suis pas sûr si cela va entraîner des répercussions négatives. On espère qu'ils vérifier pour voir si une fonction est attribuée avant de l'appeler c'est à dire si (fenêtre.onload) de la fenêtre.onload();].

Maintenant appeler initAll() ce que nous disons, c'est:

window.onload = initAll();

qui pourrait tout aussi bien dire:

window.onload = 12;

Mais quand nous disons initAll sans les parenthèses, ce que nous sommes vraiment dire, c'est: je veux remplacer quelle que soit ma fenêtre.onload fonction est, avec une nouvelle fonction, c'est à dire que je veux le remplacer par mon initAll fonction, de sorte que tous les appels à la fenêtre.onload va mon initAll code:

Donc:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

est remplacé par:

window.onload = function() {
    return 12;
}

Donc tout appel à la fenêtre.onload exécutera votre initAll fonction de la place de ce que la fenêtre.onload était à l'origine. Vous avez remplacé la fonction d'origine avec votre nouvelle fonction.

En fait, vous pourriez également écrire:

window.onload = function() {
    //Write all your init code right in here instead of having a separate 
    //initAll function.
}

Un autre exemple qui peut démontrer le mieux, c'est ceci:

var d = new Date();
var currentTime = d.getTime();

Quel que soit le temps était à l'époque d est définie finit attribué à l'heureactuelle. Grande, mais qui est seulement utile si nous voulons savoir à quelle heure la fonction contenant le code a été appelée à - dire au temps de chargement de page. Si nous voulons l'heure actuelle tout le temps que currentTime est appelé?

var currentTime = function() {
    var d = new Date();
    return d.getTime();
}

var a = currentTime(); //The current time at the point a is defined...
var b = currentTime;   //b is a functional reference to currentTime...
var c = b(); //The current time when variable c is defined
var d = c; //The current time when variable c was defined

Remarquez comment nous appelons b() dans notre c et d affectations exactement comme l'on pourrait appeler currentTime()?

17voto

Peter Bailey Points 62125

Des fonctions en javascript sont des citoyens de première classe, et en tant que tel, peut être affecté à d'autres variables ou passés comme arguments.

Donc, quand vous ne

window.onload = initAll;

Vous êtes réglage de l' onload de la propriété de l' window de la initAll fonction elle-même.

Lorsque vous ne

window.onload = initAll();

Vous êtes réglage de l' onload propriété pour contenir la valeur de retour de initAll, depuis qu'il s'exécutera en place sur cette ligne.

12voto

Andris Points 6932

initAll est une référence à une valeur de fonction et l'opérateur de crochets ajouté au nom de fonction exécute cet objet de fonction.

Donc si vous faites quelque chose comme

 a = initAll
 

alors a deviendra identique à initAll - par exemple vous pouvez faire a() - mais avec

 a = initAll()
 

la variable a obtiendra la valeur de retour de la fonction initAll exécutée

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X