JavaScript関数では、オプションで return ステートメントを使用します。それはキーワードです。しかし、return
自体の実際のタイプは何ですか。実際に、例を見て混乱しました。
function add(a, b) {
return (
console.log(a + b),
console.log(arguments)
);
}
add(2, 2);
出力:
4
[2, 2]
したがって、カンマ区切りの式をreturn
ステートメントに渡すことができます。これは機能ですか?
そして、これから始めて、JavaScriptのすべてのキーワードが最終的に関数であるという思い込みをつかむことができますか?
私はこの議論の要旨として小さなブログを書きました。確認してください here 。
しかし、実際のタイプの「リターン」自体は何ですか。
型がなく、値ではありません。
typeof return;
はUnexpected token return
。
そのため、カンマ区切りの式をreturnステートメントに渡すことができます。これは機能ですか?
いいえ、かっこcanを使用して関数を呼び出しますが、ここでは グループ化演算子 であり、 コンマ演算子 で区切られたいくつかの式を含んでいます。
より有用なデモは次のとおりです。
function add(a, b) {
return (
(a + b),
(a - b)
);
}
console.log(add(2, 2));
どの出力0
の結果はa + b
は無視され(カンマ演算子のLHS上にあります)、a - b
が返されます。
ここに誰も直接参照していないことにちょっとショックを受けました 仕様 :
12.9 returnステートメントの構文ReturnStatement:return; return [ここにはLineTerminatorはありません] Expression;
セマンティクス
FunctionBody内にないreturnステートメントが含まれている場合、ECMAScriptプログラムは構文的に正しくないと見なされます。 returnステートメントにより、関数は実行を停止し、呼び出し元に値を返します。 Expressionが省略された場合、戻り値は未定義です。それ以外の場合、戻り値はExpressionの値です。
ReturnStatementは次のように評価されます。
式が存在しない場合は、_
(return, undefined, empty)
_を返します。exprRef
をExpressionの評価結果とします。 _(return, GetValue(exprRef), empty)
_を返します。
そのため、仕様のため、例は次のようになります。
return ( GetValue(exprRef) )
ここでexprRef = console.log(a + b), console.log(arguments)
カンマ演算子の仕様 ...
セマンティクス
生成式Expression:Expression、AssignmentExpressionは、次のように評価されます。
_Let lref be the result of evaluating Expression. Call GetValue(lref). Let rref be the result of evaluating AssignmentExpression. Return GetValue(rref).
_
...は、コンマリスト内の最後の項目が割り当て式になるまで、すべての式が評価されることを意味します。あなたのコードreturn (console.log(a + b) , console.log(arguments))
は
1.)_a + b
_の結果を出力します
2.)実行するものが残っていないので、次の式を実行します
3.)arguments
を出力します。これは、console.log()
がreturnステートメントを指定していないためです。
4.)未定義に評価する
5.)呼び出し元に返されます。
したがって、正しい答えは、return
には型がなく、何らかの式の結果を返すだけです。
次の質問:
そのため、カンマ区切りの式をreturnステートメントに渡すことができます。これは機能ですか?
いいえ。JavaScriptのコンマは、複数の式を1行に結合できるように定義された演算子であり、リストの最後にある評価された式を返すように仕様で定義されています。
あなたはまだ私を信じていないのですか?
_<script>
alert(foo());
function foo(){
var foo = undefined + undefined;
console.log(foo);
return undefined, console.log(1), 4;
}
</script>
_
そのコードで遊んでください here そしてリストの最後の値を台無しにしてください。それは常にリストの最後の値を返します。あなたの場合はたまたま_undefined.
_です
最後の質問として、
そして、これから始めて、JavaScriptのすべてのキーワードが最終的に関数であるという思い込みをつかむことができますか?
繰り返しますが、いいえ。 関数には非常に具体的な定義があります 言語で。この回答はすでに非常に長くなっているため、ここでは再版しません。
括弧で囲まれた値を返すときに何が起こるかをテストします。
function foo() {
return (1, 2);
}
console.log(foo());
答えを与える2
、したがって、値のコンマ区切りリストはリストの最後の要素に評価されるように見えます。
実際、括弧はここでは無関係です。関数呼び出しを示すのではなく、操作をグループ化しています。ただし、おそらく驚くべきことは、ここでコンマが有効であることです。ここで、コンマの処理方法に関する興味深いブログ記事を見つけました。
https://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/
return
は関数ではありません。それは、それが発生する関数の継続です。
ステートメントalert (2 * foo(bar));
について考えてください。ここで、foo
は関数の名前です。それを評価しているとき、foo(bar)
の評価に専念するために、ステートメントの残りをしばらく取っておかなければならないことがわかります。 alert (2 * _)
のようなものとして脇に置いた部分を、空白を埋めて視覚化することができます。foo(bar)
の値がわかったら、それを再度選択します。
取っておいたものは、コールfoo(bar)
の-継続でした。
return
を呼び出すと、その継続に値が送られます。
foo
内でfunctionを評価すると、残りのfoo
はその関数が値に減少するのを待ってから、foo
が再び取得します。まだfoo(bar)
を評価する目標がありますが、それは一時停止しています。
return
内でfoo
を評価すると、foo
のどの部分も値を待ちません。 return
は、それを使用したfoo
内の場所の値に減少しません。代わりに、callfoo(bar)
全体を値に減らし、「evaluate foo(bar)
」という目標は完了したとみなされ、吹き飛ばされます。
プログラミングを始めたばかりのとき、人々は通常、継続について教えません。 are人々が最終的にdo継続する非常に高度なものがあるという理由だけで、彼らはそれを高度なトピックと考えています。しかし、真実は、関数を呼び出すたびにそれらをずっと使用しているということです。
return
は赤いニシンです。おそらく興味深いのは、次のバリエーションです。
function add(a, b) {
return (
console.log(a + b),
console.log(arguments)
);
}
console.log(add(2, 2));
最終行として出力します
undefined
関数は実際には何も返さないためです。 (もしあれば、2番目のconsole.log
の戻り値を返します)。
そのままで、コードはまったく同じです
function add(a, b) {
console.log(a + b);
console.log(arguments);
}
console.log(add(2, 2));
return ステートメントを理解する興味深い方法は void 演算子を使用することですこのコードを見てください
_var console = {
log: function(s) {
document.getElementById("console").innerHTML += s + "<br/>"
}
}
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) );
_
_<div id="console" />
_
return
ステートメントは_[[expression]]
_という1つの引数を取り、これをスタック上の呼び出し元、つまり_arguments.callee.caller
_に返すため、void(expression)
を実行してからundefined
これはvoid演算子の評価です。