2014-01-04 16 views
49

私はJavaScriptプログラミングのコースを受講しており、講師は典型的なJavaScript関数が常に値を返すと言っています。明示的な戻り値を指定しない場合でも、エンジンはundefinedを返します。なぜJavaScript関数が常に値を返すのですか?

本当ですか?もしそうなら、なぜですか?

+1

ファンクションの戻り値がない場合(たとえば、変数に代入した場合など)、fuctionの戻り値は何に含まれるべきですか? :)))私はそれが '未定義'であるべきだと思います。それ以外に何ができますか? :) –

+0

すべての関数が何かを返すならば、jsエンジンを書くほうが簡単です。不明なプロパティも不定になります。今ではそれが未定義の代わりにテール値を返した場合... – dandavis

答えて

82

それは本当-ためだということではJavaScriptを設計した方法です。

しかし、私はそれがあなたが探していた答えだとは思わないので、それについて考えてみましょう...
JavaScriptを設計した人の服に入れてみましょう! 静的言語で

は、通常return何か(void機能)ない関数、およびいくつかの値を返す関数の区別があります。 Brendanは、動的言語を設計することを選択しました。つまり、関数の戻り型を定義する必要がない言語です。したがって、JavaScript は、という関数から返されたものをチェックせず、完全な自由を与えます。

あなたは...

function computeSomething() { 
    return 2; 
} 

...または文字列を数値を返す関数を持つことができます...

function computeSomething() { 
    return 'hi'; 
} 

...または、実際には、それらのいずれか:

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

時々、あなたは何-だけ SOMETを行うに必要な計算をする必要はありません。ヒンジ。
あなたは何も返さない。

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

我々は、しかし、それの真ん中に機能を終了する場合があり、そしてreturn <value>はすでに、まさにそれをを行いますので、このユースケースをサポートするために、値なしでreturnを書いて許可するように理にかなって:

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

    while (true) { 
    doSomethingElse(); 
    } 
} 

これは、JavaScriptの採用を確実にする目標の1つであるC/Java構文と一貫しています。

私は平らなものを計算することになっているものにreturnを置くとどうなりますか? 私たちはこれを禁止することはできません:これまでの決定のうちの1つは、JavaScriptを動的言語にすることでした。ここでは、関数が返すものをチェックしません。もちろん

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); // ??? 

ブレンダンは、この場合にエラーが発生することを決定している可能性が、それは見つけにくいエラーとあまりにも簡単に破壊可能なコードにつながるので、彼は賢明ではないことを決めました。

したがって、空のreturnは "return undefined"という意味を持っています。

しかし、関数の早い段階、または終わりの違いは何ですか?呼び出しコードの観点からは、何もあるべきではありません。呼び出しコードは、を知っているとは限りません。それは戻り値(もしあれば)だけに関心があります。

したがって、関数が明示的なreturn <value>演算子を介して関数を指定しない場合、undefinedを「デフォルト」の戻り値にすることが唯一の論理的結論です。したがって、returnと関数実行済みのセマンティクスは一致します。

JavaScriptの前にある別の動的言語Pythonは、同じようにこの問題を解決します。None is returned if function doesn't specify return value

+8

人々はいつもJavaScriptの悪い部分をほのめかしています。少数ながらも少数ながら、単に美しい言葉がたくさんあります。 –

+7

すばらしい答え!仕様の一部を逆戻りさせるのではなく、この設計上の意義と理由を分析します。 – Peter

+2

「デフォルト/未定義」値の考え方は、一般的に言語の概念として有用です。ひとつ紹介したら、(JSのように)引数が渡されたかどうかを調べるなどの簡単なことができますし、void関数からundefinedを返さないのは奇妙です。 –

5

明示的な戻り値を指定しない場合でも、エンジンは「未定義」を返します。本当?

実際はありません。私が理解しているように、何も返さない関数は何も返しません。つまり、そのような関数呼び出しの結果に変数を代入すると、式は undefinedと評価されます。私は修正スタンド

EDIT

。ここでは、仕様の関連部分です:[[呼び出し]]

Fはこの値で呼び出される関数オブジェクトの[[]呼び出す]内部メソッド


13.2.1と引数のリストは、以下のステップがとられています。

  1. レッツfuncCtxは、Fの[[FormalParameters]]内部プロパティ、渡された引数リスト引数の値を使用して機能コードのための新しい実行コンテキストを確立する結果であります10.4.3で説明したこの値。
  2. Fの[[Code]]内部プロパティの値であるFunctionBodyを評価した結果をresultとします。 Fに[[Code]]内部プロパティがない場合、またはその値が空のFunctionBodyである場合、resultは(normal、undefined、empty)です。
  3. 実行コンテキストfuncCtxを終了して、前の実行コンテキストを復元します。
  4. result.typeがthrowの場合は、result.valueをスローします。
  5. result.typeがreturnの場合は、result.valueを返します。
  6. それ以外の場合は、result.typeは正常でなければなりません。定義されていない戻り値。
+4

厳密には、これは[not true](http://stackoverflow.com/a/20915520/458193)です。 –

+2

ありがとう@ダン - 私はいくつかのupvotesとブロンズのバッジが私が提供することができるすべての報酬について約二倍だと思っています:) –

+1

"何も返しません...何も返しません"という関数はtrueではありません。 JSには「何もない」価値はありません。値を持たないreturn文に対しては、 "正確には '未定義'を返します。参照:12.9 ECMA仕様のreturn文。 –

2

機能はオブジェクトです。あなたが他のオブジェクトを割り当てることになると解釈値決定強制するようしたがって、常に変数に機能を割り当てることができる(未定義されてもよい。)

+0

これは関数オブジェクトに関するものではなく、関数呼び出しに関するものです。 – bfavaretto

11

だつまりによってECMAScript specification

13.2.1 [ [電話]] ... 6.それ以外の場合、result.typeは正常でなければなりません。定義されていない戻り値。それが最後にreturn undefined;暗黙の持っているかのように

は、本質的に任意のJS関数がコンパイルされます。

function foo() { 
    ... 

    return undefined; // implicit non-visible statement 
} 
関連する問題