95 votes

Quel est le type du mot-clé "return" ?

Nous utilisons retourner en option dans les fonctions JavaScript. C'est un mot-clé. Mais quel est le type réel de return lui-même. En fait, j'ai été confus en voyant l'exemple :

function add(a, b) {
  return (
    console.log(a + b),
    console.log(arguments)
  );
}

add(2, 2);

Sortie :

4
[2, 2]

Ainsi, nous pouvons passer des expressions séparées par des virgules dans la fonction return déclaration. Est-ce une fonction ?

Et en commençant par cela, pouvons-nous supposer que tous les mots clés en JavaScript sont en fin de compte une fonction ?

J'ai écrit un petit blog qui reprend l'essentiel de cette discussion. Vous pouvez le consulter ici .

129voto

Quentin Points 325526

Mais quel est le type réel de "retour" lui-même.

Il n'a pas de type, ce n'est pas une valeur.

Tentative de typeof return; vous donnera Unexpected token return .

Ainsi, nous pouvons passer des expressions séparées par des virgules dans l'instruction de retour. Est-ce une fonction ?

Non, alors que la parenthèse peut être utilisé pour appeler une fonction, ici il s'agit d'un opérateur de groupage contenant un couple d'expressions séparées par un opérateur de virgule .

Une démonstration plus utile serait :

function add(a, b) {
  return (
    (a + b),
    (a - b)
  );
}

console.log(add(2, 2));

Quelles sorties 0 car le résultat de a + b est ignoré (il se trouve à la gauche de l'opérateur virgule) et a - b est renvoyé.

32voto

avgvstvs Points 946

Je suis un peu choqué que personne ici n'ait directement référencé la spécification :

12.9 L'instruction return Syntaxe ReturnStatement : return ; return [pas de LineTerminator ici] Expression ;

Sémantique

Un programme ECMAScript est considéré comme syntaxiquement incorrect s'il contient une instruction de retour qui ne se trouve pas dans un FunctionBody. A déclaration de retour fait en sorte qu'une fonction cesse son exécution et renvoie une à l'appelant. Si l'expression est omise, la valeur de retour est indéfinie. Sinon, la valeur de retour est la valeur de Expression.

Un ReturnStatement est évalué comme suit :

Si l'Expression n'est pas présente, retour (return, undefined, empty) . Soit exprRef être le résultat de l'évaluation de l'expression. Retourner (return, GetValue(exprRef), empty) .

Donc, à cause de la spécification, votre exemple se lit comme suit :

return ( GetValue(exprRef) )

exprRef = console.log(a + b), console.log(arguments)

Ce qui, selon le spec sur l'opérateur virgule ...

Sémantique

La production Expression : Expression , AssignmentExpression est évaluée comme suit :

Let lref be the result of evaluating Expression.
Call GetValue(lref).
Let rref be the result of evaluating AssignmentExpression.
Return GetValue(rref).

...signifie que chaque expression sera évaluée jusqu'au dernier élément de la liste à virgule, qui devient l'expression d'affectation. Donc votre code return (console.log(a + b) , console.log(arguments)) va

1.) imprimer le résultat de a + b

2.) Il ne reste rien à exécuter, alors on exécute l'expression suivante qui

3.) imprime le arguments et parce que console.log() ne spécifie pas de déclaration de retour

4.) Évalue à une valeur indéfinie

5.) Qui est ensuite renvoyé à l'appelant.

Donc la bonne réponse est, return n'a pas de type, il renvoie seulement le résultat d'une expression.

Pour la prochaine question :

Ainsi, nous pouvons passer des expressions séparées par des virgules dans l'instruction de retour. Est-ce une fonction ?

Non. La virgule en JavaScript est un opérateur, défini pour vous permettre de combiner plusieurs expressions sur une seule ligne, et est définie par la spécification pour renvoyer l'expression évaluée de ce qui est le dernier dans votre liste.

Tu ne me crois toujours pas ?

<script>
alert(foo());
function foo(){
    var foo = undefined + undefined;
    console.log(foo);
    return undefined, console.log(1), 4;
}
</script>

Jouez avec ce code ici et s'amuser avec la dernière valeur de la liste. Il retournera toujours la dernière valeur de la liste, dans votre cas il s'agit de undefined.

Pour votre dernière question,

Et en commençant par ça, peut-on supposer que tous les mots clés en JavaScript sont en fin de compte une fonction ?

Encore une fois, non. Les fonctions ont une définition très spécifique dans la langue. Je ne la reproduirai pas ici car cette réponse devient déjà extrêmement longue.

15voto

SpoonMeiser Points 6211

Test de ce qui se passe lorsque vous renvoyez des valeurs entre parenthèses :

function foo() {
    return (1, 2);
}

console.log(foo());

Donne la réponse 2 Il apparaît donc qu'une liste de valeurs séparées par des virgules est évaluée au dernier élément de la liste.

Vraiment, les parenthèses ne sont pas pertinentes ici, elles regroupent des opérations au lieu de signifier un appel de fonction. Ce qui est peut-être surprenant, cependant, c'est que la virgule est légale ici. J'ai trouvé un article de blog intéressant sur la façon dont la virgule est traitée ici :

https://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/

9voto

return n'est pas une fonction. C'est le continuation de la fonction dans laquelle il intervient.

Réfléchissez à l'affirmation suivante alert (2 * foo(bar));foo est le nom d'une fonction. Lorsque vous l'évaluez, vous voyez que vous devez mettre de côté le reste de l'instruction pour vous concentrer sur l'évaluation de la fonction. foo(bar) . Vous pourriez visualiser la partie que vous mettez de côté comme quelque chose comme alert (2 * _) avec un blanc à remplir. Lorsque vous savez quelle est la valeur de foo(bar) est, vous le reprenez.

La chose que vous avez mise de côté était le continuation de l'appel foo(bar) .

Appel à return envoie une valeur à cette continuation.

Lorsque vous évaluez un fonction à l'intérieur de foo le reste de la foo attend que cette fonction soit réduite à une valeur, puis foo reprend. Vous avez encore un objectif à évaluer foo(bar) c'est juste une pause.

Lorsque vous évaluez return à l'intérieur de foo , aucune partie de foo attend une valeur. return ne se réduit pas à une valeur à l'endroit à l'intérieur de foo où vous l'avez utilisé. Au lieu de cela, il fait en sorte que la totalité appelez foo(bar) à réduire à une valeur, et l'objectif "évaluer foo(bar) " est considéré comme complet et soufflé.

Les gens ne vous parlent généralement pas des continuations lorsque vous débutez en programmation. Ils pensent que c'est un sujet avancé, juste parce qu'il y a sont des choses très avancées que les gens finissent par faire avec continuations. Mais en réalité, vous les utilisez depuis le début, chaque fois que vous appelez une fonction.

6voto

ths Points 1218

Le site return est un hareng rouge. La variation suivante est peut-être intéressante :

function add(a, b) {
  return (
    console.log(a + b),
    console.log(arguments)
  );
}

console.log(add(2, 2));

qui produit comme dernière ligne

undefined

car la fonction ne renvoie rien. (Elle renverrait la valeur de retour de la deuxième fonction console.log s'il en avait un).

En l'état, le code est exactement identique à celui de

function add(a, b) {
    console.log(a + b);
    console.log(arguments);
}

console.log(add(2, 2));

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