52 votes

Pourquoi les fonctions JavaScript renvoient toujours une valeur ?

Je suis un cours de programmation JavaScript, et l'instructeur a dit qu'une fonction JavaScript typique renvoie toujours une valeur. Même lorsque nous ne fournissons pas de valeur de retour explicite, les moteurs retournent undefined .

Est-ce que c'est vrai ? Si oui, pourquoi ?

91voto

Dan Points 16670

C'est vrai - parce que c'est ainsi que JavaScript a été conçu.

Mais je ne pense pas que ce soit la réponse que tu cherchais, alors réfléchissons...
Essayez de vous mettre à la place de Brendan Eich la personne qui a conçu JavaScript.

Sur statique Dans les langages, il existe généralement une distinction entre une fonction qui n'est pas retourner n'importe quoi ( void ), et une fonction qui renvoie une certaine valeur. Brendan a choisi de concevoir une dynamique c'est-à-dire un langage qui ne nécessite pas de définir les types de retour des fonctions. Ainsi, JavaScript ne vérifie pas ce que vous retournez de la fonction pour vous donner une liberté totale.

Vous pouvez avoir une fonction qui renvoie un nombre...

function computeSomething() {
  return 2;
}

... ou une chaîne ...

function computeSomething() {
  return 'hi';
}

... ou, en fait, n'importe lequel d'entre eux :

function computeSomething() {
  if (Math.random() > 0.5) {
    return 2;
  } else {
    return 'hello';
  }
}

Parfois, vous n'avez pas besoin de calculer quoi que ce soit, vous avez seulement besoin de faire quelque chose.
Donc vous ne rendez rien.

function doSomething() {
   console.log('doing something');
}

Nous pouvons cependant vouloir quitter une fonction au milieu de celle-ci, et puisque return <value> le fait déjà exactement cela il est logique d'autoriser l'écriture return sans valeur pour soutenir ce cas d'utilisation :

function doSomething(num) {
   if (num === 42) {
     return;
   }

   while (true) {
     doSomethingElse();
   }
}

Cela est également conforme à la syntaxe C/Java, ce qui était l'un des objectifs pour assurer l'adoption de JavaScript.

Oui, c'est là que le bât blesse : que se passe-t-il si on met un simple return dans une fonction censée calculer quelque chose ? Notez que on ne peut pas interdire ça L'une de nos premières décisions a été de faire de JavaScript un langage dynamique, dans lequel nous ne vérifions pas ce que la fonction renvoie.

function computeSomething(num) {
  if (num === 42) {
    return; // just return? o_O
  }

  if (Math.random() > 0.5) {
    return 2;
  } else {
    return 'hello';
  }
}

var x = computeSomething(2); // might be 2, might be 'hello'
var y = computeSomething(42); // ???

Bien sûr, Brendan aurait pu décider de lever une erreur dans ce cas, mais il a sagement décidé de ne pas le faire, car cela conduirait à des erreurs difficiles à trouver et à un code trop facilement cassable.

Donc un vide return a obtenu un sens "retour undefined ".

Mais quelle est la différence entre une fonction qui revient tôt ou à la fin ? Il ne devrait pas y en avoir, du point de vue du code appelant. Le code appelant n'est pas censé connaître quand exactement la fonction a retourné ; il est seulement intéressé par la valeur de retour (si elle existe).

La seule conclusion logique serait donc de faire undefined la valeur de retour "par défaut" si la fonction n'en spécifie pas une par le biais d'une commande explicite. return <value> opérateur. Ainsi, return et la sémantique de la fonction exécutée jusqu'à la fin correspond.

Python, un autre langage dynamique qui a précédé JavaScript, résout ce problème de la même manière : None est retourné si la fonction ne spécifie pas de valeur de retour. .

13voto

c-smile Points 8609

C'est par Spécification ECMAScript

13.2.1 [[Call]] ... 6. Sinon, result.type doit être normal. Retourner undefined.

En fait, toutes les fonctions JS sont compilées comme si elles avaient un caractère implicite. return undefined; à la fin :

function foo() {
  ...

  return undefined; // implicit non-visible statement  
}

7voto

Adam Rackis Points 45559

Même lorsque nous ne fournissons pas de valeur de retour explicite, les moteurs renvoient "undefined". Est-ce que c'est vrai ?

Pas vraiment. Si je comprends bien, une fonction qui ne renvoie rien... ne renvoie rien. Cela dit, si vous affectez une variable au résultat d'une telle invocation de fonction, l'expression sera évaluée comme suit undefined .

EDITAR

Je me suis trompé. Voici la partie pertinente de la spécification :


13.2.1 [[Appels]]

Lorsque la méthode interne [[Call]] d'un objet Function F est appelée avec une valeur this et une liste d'arguments, les étapes suivantes sont réalisées :

  1. Soit funcCtx le résultat de l'établissement d'un nouveau contexte d'exécution pour le code de fonction en utilisant la valeur de la propriété interne [[FormalParameters]] de F, les arguments passés Liste args, et la valeur this comme décrit dans 10.4.3.
  2. Soit le résultat de l'évaluation du CorpsDeFonction qui est la valeur de la propriété interne [[Code]] de F. Si F ne possède pas de propriété interne [[Code]] ou si sa valeur est un FunctionBody vide, alors le résultat est (normal, indéfini, vide).
  3. Quitter le contexte d'exécution funcCtx, en restaurant le contexte d'exécution précédent.
  4. Si result.type est throw, alors throw result.value.
  5. Si result.type est return, alors return result.value.
  6. Sinon, result.type doit être normal. Retourner undefined.

2voto

canadaCoder Points 591

En javascript, les fonctions sont des objets. Par conséquent, vous pouvez toujours assigner une fonction à une variable comme vous le feriez pour n'importe quel autre objet et l'interpréteur déterminera de force une valeur (qui peut être indéfinie.)

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