85

先ほどこの質問をしましたが、このトピックについてもう少し考えてみると、「ステートメント」と「表現」という用語の意味のあいまいな境界線はどこにあるのだろうと思い始めました。すべてのステートメントは式でもありますか? REPLコンソールの戻り値はどこから来るのですか? それらは常に直感的に理解できるとは限りません。もちろん、 と入力1+1すると が得られますが2、ロジックが何であるかが明らかでない場合もあります。

REPL に入力されたものは何らかの値を生成するとすれば、JS ソース コードで式とスタンドアロン ステートメントの両方として使用できるということですか?

_X_次のスニペットで使用できるコードの文字列を使用することも_Y_、その逆も可能ですか?if(_X_) _Y_

4

11 に答える 11

62

すべてのステートメントは式でもありますか?

「JavaScript がステートメントを期待するところはどこでも、式を書くこともできます。このような文を式文と呼びます。逆は成立しません: JavaScript が式を期待するステートメントを書くことはできません。たとえば、if ステートメントを関数の引数にすることはできません。」</p>

これは、このトピックに関する Axel Rauschmayer による最近の投稿からのものです: JavaScript における式とステートメント

それが役に立てば幸い。

于 2012-10-03T06:55:07.610 に答える
51

MDNによると:

式は、値に解決される任意の有効なコード単位です。

そのため、右辺値として使用できるものはすべて式です。

基準は、副作用が存在するかどうかではありません。式には間違いなく副作用があります。たとえばa=2、値 (2) を持ち、変数に値を代入する式です。そのため、次のようなことができます。

let a;
let b = 1 + (a = 2); // a is now 2 and b is 3

コンテキストによっては、同じ (テキスト) コード ブロックが式とステートメントの両方と見なされる可能性があります。たとえば、テキスト スニペットfunction f(){}は、次のコードの 1 行目の式と 2 行目のステートメントです。

let g = function f() {};
function f() {};

したがって、何かが式であるかステートメントであるかは、(一般的なケースでは) 文脈から外れたテキスト コードを見て判断することはできません。むしろ、それは構文ツリー内のノードのプロパティであり、コードが (精神的にまたは実際に) 解析された後にのみ決定できます。

また、おそらくもっと重要なこととして、関数内の関数ステートメント (別名関数宣言) は、関数が呼び出さfれたときに作成される実行コンテキストの一部を形成します。fただし、関数式はその実行コンテキストの一部を形成しません。

よく引用される影響の 1 つは、関数宣言は「持ち上げられる」のに対し、関数式はそうではないということです。

関数ステートメントは実行コンテキストでスペースを占有しますが、関数式は占有しないため、深層再帰ではより微妙な効果が実験的に観察されます。たとえば、以下のコードは関数の無限再帰を使用していますf。最初のケースの関数fには関数式が含まれており、2 番目のケースでは同等の関数宣言が含まれています。

// Function Expression
{
    let i = 0;
    try {

        function f () {
            i++;
            (function g() {})(); // this is an expression
            f();
        }

        f();

    } catch (err) {
        console.log(`Function Expressions case: depth of ${i} reached. Error: ${err.name}`);
    }
}
// Function Declaration
{
    let i = 0;
    try {
        function f () {
            i++;
            function g() {}; // this is a statement
            g();
            f();
        }

        f();

    } catch (err) {
        console.log(`Functions Declarations case: depth of ${i} reached. Error: ${err.name}`);
    }
}

私のマシンでは、一貫して以下を取得します(node.jsで):

Function Expressions case: depth of 17687 reached. Error: RangeError
Functions Declarations case: depth of 15476 reached. Error: RangeError

…これは、関数宣言が実行コンテキストを保持するために必要なスペースの量を増やし、スタックスペースを少し速く消費し、最大再帰の深さをわずかに減らすという事実と一致しています。

于 2016-04-06T15:44:14.773 に答える
31

簡単に言うと、を評価して値を生成します。一方、ステートメントは何かを実現するために実行されます。

于 2016-07-13T10:14:58.793 に答える
22

式は何らかの値を生成または評価します。

式の例: new Date()副作用なしで新しい Date オブジェクトを生成します。 [1,2,3]副作用なしで新しい配列を生成します。 5+6新しい値を生成する 11.副作用なしで新しい値を生成するだけです。

ステートメントは何らかの動作を生成するか、何かを行いますが、副作用もあります。副作用に基づいて、ステートメントを分類できます。

x=5;はステートメントであり、ここでの副作用は x の代入または変更です。

setTimeout()- タイマーの開始は副作用です。

通常、ステートメントはセミコロンで区切られます。

式ステートメントは、何らかの副作用を持つ式、または単に「副作用のある式」です。

式ステートメントの例:

x+=6;複雑な式(一次式のグループ)は、副作用である代入を行っている、いわゆる式ステートメントです。

delete a[2];
于 2013-11-06T10:50:27.780 に答える
9

JavaScript のすべてのプログラムはステートメントで構成され、0 個以上のステートメントをグループ化するために使用されるブロック ステートメントを除いて、セミコロンで終わります。ステートメントはいくつかのアクションを実行するだけですが、値や出力を生成しませんが、は何らかの値を返します。インタープリターが式を見ると、その値を取得し、式を新しい値に置き換えます。ステートメントは、これらの式を操作するために使用されます。ここで式かステートメントかを確認できます: JavaScript パーサー

于 2016-11-22T18:11:49.913 に答える