Quel type est le mot clé ‘return’?

Nous utilisons éventuellement des instructions de retour dans les fonctions JavaScript. C’est un mot clé. Mais quel est le type de return proprement dit? En fait, je me suis trompé en voyant l’exemple:

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

Sortie:

 4 [2, 2] 

Nous pouvons donc passer des expressions séparées par des virgules dans la déclaration de return . Est-ce une fonction?

Et à partir de là, pouvons-nous supposer que chaque mot clé dans JavaScript est finalement une fonction?

J’ai écrit un petit blog en tant qu’élément essentiel de cette discussion. Vous voudrez peut-être le vérifier ici .

Mais quel est le type même 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 .

Nous pouvons donc passer des expressions séparées par des virgules dans la déclaration de retour. Est-ce une fonction?

Non, alors que les parenthèses peuvent être utilisées pour appeler une fonction, elles sont ici un opérateur de regroupement contenant quelques 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)); 

Qui renvoie 0 car le résultat de a + b est ignoré (il se trouve sur le LHS de l’opérateur virgule) et a - b est renvoyé.

Je suis un peu choqué que personne ici n’ait directement référencé les spécifications :

12.9 La déclaration de retour Syntaxe ReturnStatement: return; retourne [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. Une instruction return provoque la cessation de l’exécution d’une fonction et renvoie une valeur à l’appelant. Si Expression est omis, 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, retournez (return, undefined, empty) . Soit exprRef le résultat de l’évaluation Expression. Retour (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)

Qui selon les spécifications sur l’opérateur de 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 de virgules, qui devient l’expression d’affectation. Donc, votre code return (console.log(a + b) , console.log(arguments)) va

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

2.) Il ne rest rien à exécuter, alors exécutez l’expression suivante qui

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

4.) Évalue à indéfini

5.) Qui est ensuite retourné à l’appelant.

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

Pour la prochaine question:

Nous pouvons donc passer des expressions séparées par des virgules dans la déclaration de retour. Est-ce une fonction?

Non. La virgule dans JavaScript est un opérateur, défini pour vous permettre de combiner plusieurs expressions dans une seule ligne, et est défini par la spécification pour renvoyer l’expression évaluée de la dernière de votre liste.

Tu ne me crois toujours pas?

  

Jouez avec ce code ici et jouez avec la dernière valeur de la liste. Il retournera toujours la dernière valeur de la liste, dans votre cas, il se trouve qu’il n’est undefined.

Pour votre dernière question,

Et à partir de là, pouvons-nous supposer que chaque mot clé dans JavaScript est finalement une fonction?

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

Test de ce qui se passe lorsque vous retournez 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 évalue le dernier élément de la liste.

En réalité, les parenthèses ne sont pas pertinentes ici, elles regroupent les opérations au lieu de signifier un appel de fonction. Ce qui est peut-être surprenant, c’est que la virgule est légale ici. J’ai trouvé un article intéressant sur la manière dont la virgule est traitée ici:

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

return n’est pas une fonction. C’est la continuation de la fonction dans laquelle elle se produit.

Pensez à l’ alert (2 * foo(bar)); énoncé 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 rest de la déclaration pendant un moment pour vous concentrer sur l’évaluation de foo(bar) . Vous pouvez visualiser la partie que vous avez mise de côté comme quelque chose comme alert (2 * _) , avec un blanc à remplir. Lorsque vous savez quelle est la valeur de foo(bar) , vous la reprenez.

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

Le return appel génère une valeur pour cette suite.

Lorsque vous évaluez une fonction dans foo , le rest de foo attend que cette fonction soit réduite à une valeur, puis foo reprend le foo . Vous avez toujours un objective pour évaluer foo(bar) , il est juste en pause.

Lorsque vous évaluez le return intérieur de foo , aucune partie de foo n’attend une valeur. return ne se réduit pas à l’intérieur de foo où vous l’avez utilisé. Au lieu de cela, cela fait que l’ appel total foo(bar) réduit à une valeur et que l’objective “évaluer foo(bar) ” est considéré comme complet et époustouflé.

Les gens ne vous parlent généralement pas des continuations lorsque vous êtes novice en programmation. Ils le considèrent comme un sujet avancé, simplement parce qu’il y a des choses très avancées que les gens font éventuellement avec les continuations. Mais la vérité est que vous les utilisez tout le temps, chaque fois que vous appelez une fonction.

le return ici est un hareng rouge. Peut-être intéressant est la variation suivante:

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

qui produit la dernière ligne

 undefined 

comme la fonction ne retourne rien. (Il renverrait la valeur de retour de la seconde console.log si elle en avait une).

Tel quel, le code est exactement identique à

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

Un moyen intéressant de comprendre la déclaration de retour est à travers l’opérateur void Jetez un coup d’oeil à ce code

 var console = { log: function(s) { document.getElementById("console").innerHTML += s + "
" } } function funReturnUndefined(x,y) { return ( void(x+y) ); } function funReturnResult(x,y) { return ( (x+y) ); } console.log( funReturnUndefined(2,3) ); console.log( funReturnResult(2,3) );