1.ステートメントと式
JavaScriptの式と文は異なる。式は、関数呼び出しの引数として、例えば、値を任意の場所に配置必要とすることができる値を生成する。次のコード行の各々は式であります:
MYVAR
3 + X
myfunc関数( "A"、 "B")
ステートメントは、動作ループとして、文は、典型的な声明であれば理解することができる。.JavaScriptプログラムがあなたの代わりに式を使用することができ、いくつかの必要な文の一連のステートメントである。このような文が呼ばれます式文ではなく、その逆の場合:あなたは、このような表現の代わりに文を置くことができない文がパラメータとして機能することができない場合は、必要になります。
2.その他の文法
彼らは彼らを知って取得した後、私たちはより良い文と式の間の関係を理解することができ、同様の構文は、次の2ペアを考えてみましょう。
2.1 if文と条件演算子
ここではif文の例は次のとおりです。
VaRのX;
もし(Y> = 0){
X = Y。
}他{
X = -y。
}
文関数式は、条件演算子と呼ばれる同様場合。上記のステートメントは、以下と等価です。
VAR X =(Y> = 0:Y)。
等号=とセミコロンでは、コードは括弧が必要とされていない両側間の条件式であるが、私は括弧は、条件式を読みやすくすると思います。
2.2セミコロンとカンマ演算子
JavaScriptでは、セミコロンは二つの文に接続することができます使用します。
FOO(); バー()
珍しいコンマ演算子を使用して、2つの式を接続するには:
FOO()、バー()
前と後のコンマ演算子は2つの式を計算し、その後、右に結果を返し、例えば、表現:
> "A"、 "B" 'B' >変数X =( "A"、 "B")。 > X 'B' >はconsole.log(( "A"、 "B"))。 B
3.一見文の表現
いくつかの表現はいくつかの問題を引き起こす可能性が文、のように見えます。
3.1オブジェクトリテラルの文ブロックと
以下に、式の値を生成することができるリテラルオブジェクト、すなわちオブジェクトです。
{
FOO:バー(3,5)
}
しかし同時に、それはまた、完全に合法的な声明で、この文の不可欠な部分は、以下のとおりです。
- コードブロック:括弧で囲まれたステートメントのシーケンス。
- ラベル:あなたは、ここですべての文の前にラベルを置くことができます。fooはラベルです。
- 声明:式文のバー(3、5) 。
あなたは、JavaScriptが実際に別々のコードブロック(コードの共通ブロック文のループ上または場合依存している)次のコードは、このコードブロックの効果を実証していることをショックを受けるかもしれません:あなたはそれをラベルセットを与えることができますその後、このブロックのうち。
機能試験(printTwo){ 印刷:{ にconsole.log( "1")。 もし印刷破る(printTwo!)。 console.log( "二"); } はconsole.log( "三")。 } >テスト(偽) ワン スリー >テスト(真の) 一つ 二つ 三つ
3.2関数式と関数の宣言
次のコードは、関数式です:
関数 () { }
あなたはまた、関数式に名前を付けることができ、それが名前の(非匿名)関数式に変換されます。
関数foo(){}
関数(の名前fooは)関数内にのみ存在し、例えば、それを行うには、再帰的計算:
>のvar FACは=私を機能さ(x)は{X <= 1を返しますか?1:X *私(X-1)} > FAC(10) 3628800 >にconsole.log(ME) にReferenceError:私が定義されていません
表面から指定された関数式、および関数の宣言とは差がないが、その効果が異なる。機能的発現値(関数)アクションを実行する関数を宣言を生成します。関数が変数に割り当てられた。また、関数式のみがすぐに呼び出すことができ、それが宣言を機能することはできません。
何も追加されていない場合に限り、表現の構文として、スクリプトホスト機能は、量の直接の関数とみなされ、光機能で始まる、関数の宣言であると考えられています
競合を解決するために3.3
3.1と3.2の違いを教えてくれないことに直面して、いくつかの式と文から見ることができます。同じコードは、表現コンテキストで表示され、文の文脈に現れるさまざまな役割を示すことを意味します。一般的に状況下では、これらの2つのコンテキストは何の交差点は、ステートメントが式である場合、オーバーレイがあるだろう、しかしではありません。つまり、いくつかの表現は、この曖昧さを解決するために、JavaScriptシンタックス禁止に文のコンテキストに表示されますが存在します先頭の括弧やキーワード「機能」と式文:
ExpressionStatement: [先読み∉{ "{"、 "機能"}]式。
だから、あなたは、看板の表現で始まる文を書きたいならば、私は何をすべき?あなたは内部の括弧の中にそれを置くことができ、これは営業成績を変更しないだけで式が式の中で解析されることを保証しますコンテキストは、私たちが最初の例:.における二つの例を見てみましょう文のパラメータに基づいて、それを解決しますevalのコンテキストあなたがしたい場合。evalはオブジェクトを返し括弧は、あなたが両側にオブジェクトリテラル量を追加する必要があります。
>評価( "{FOO:123}") 123 >はeval( "({FOO:123})") {FOO:123}
第二の例:以下の例は、直ちに実行関数式です。
>(関数(){リターン"ABC"}()) 'ABC'
あなたは括弧を省略した場合は、(関数宣言は匿名にはできません)シンタックスエラーが発生します。
>関数(){リターン"ABC"}() にSyntaxError:functionステートメントは、名前が必要
あなたは、関数名を追加する場合は、(関数宣言を実行に理解することはできません)シンタックスエラーが発生します。
>関数foo(){リターン"ABC"}() にSyntaxError:構文エラー
コンテキスト式の別の許可式が解析される方法は、そのような単項演算子を使用することです + や !しかし、括弧の使用と異なるが、これらの演算子は、式の営業成績を変更するということです。あなたが気にしない場合その結果は、その後、使用することができます。
> +関数(){にconsole.log( "こんにちは")}() ハロー はNaN
NaNはある+機能の役割は、の戻り値の後に実行される未定義の結果。
翻訳者注:私は翻訳が明確ではないと思う、彼は、粗数字でレベルを描きました。
在区分表达式和语句之前,我们先分别对他们进行介绍:
1.表达式(expressions)
表达式是由运算符构成,并运算产生结果的语法结构。每个表达式都会产生一个值,它可以放在任何需要一个值的地方,比如,作为一个函数调用的参数.下面的每行代码都是一个表达式:
var a = (5 + 6) / 2; //表达式:(5 + 6) / 2 var b = (function(){ return 25;})(); //表达式: (function(){ return 25;})() foo(a*b); //表达式:a*b
2.语句(statements)
语句则是由“;(分号)”分隔的句子或命令。如果在表达式后面加上一个“;”分隔符,这就被称为“表达式语句”。它表明“只有表达式,而没有其他语法元素的语句”。
var a = (5 + 6) / 2; //整行,赋值语句 if(a>12) { statements} //条件语句 var o = {}; //赋值语句 (function(obj){ obj.b = 23;})(o||{}); //表达式语句
一般的javascript中的语句分为下面几种:
(1)声明语句:变量声明和函数声明
(2)赋值语句
(3)控制语句:能够对语句执行顺序产生改变,包括条件语句和循环语句,当然还有比较特殊的标签语句。
(4)表达式语句:这些语句去掉最后分号,都也可当表达式用的。常见的有:对象操作(new、delete)、函数调用(函数执行,必有返回值)等。
var num = 9; //声明、赋值语句 vloop: //标签语句 { //其实这里大括号可以不需要的,在这里我只想向大家展示一下这种代码块结构而已 for(var i=1; i<10; i++) { //循环语句 if(i==num){ //条件语句 break vloop; }else{ num = num - 1; } } } console.log(num); //表达式语句,输出:5
由上面可以看出,表达式和语句还是存在很大区别的,可也说表达式是语句的构成部分,而语句则又可以组成可执行代码块。一般而已,我们都可以很直观的看出两者的区别,但是,一些特殊情况就不太好区别。
难以区分的表达式和语句
1.对象字面量和代码块
var o = { a : {}, b : "string" }
上面是一个简单至极的对象字面量,但是我们单单从代码的直观层面来看,这个字面量其实跟代码块非常相似,由两个标签语句组成的感觉。复杂些上,还有上面之 前我在语句最后举得那个例子,例子中代码块位于标签语句下面,里面包含有个for循环。这时候,你说这个由{}构建的代码块是表达式呢还是语句?
2.命名函数表达式
javascript中有三种函数类型:函数声明,函数表达式和函数构造器创建的函数。
(1)函数声明(FD)
function foo(){ statements; }
(2)函数表达式(FE)
var foo = function(){ statements;}
还有一种比较特殊点的:var foo = function _foo() { statements;} ,这是时候,给函数一个供内部使用的名字_foo,所有,此时,这种类型又称:命名函数表达式(NFE)。
(3)函数构造器创建
var foo = new Function(expressions);
其实上面说了函数的三种类型并不是我们这章的主要重点,这这我们也是探讨一下FD和NFE的一些区别而已,关于其他函数内容后面我单独在细说。
是不是看到FD和NFE的形式之后,又有点点迷糊了,NFE除了前面多了一个var和变量名之外,其他和FD的结构一模一样,这样的话,那是不是说明FD既可以作声明语句,也同时可以作赋值表达式呢?
解答之前两个疑惑
鉴于上面两个比较让人迷惑的语法点,javascript它自己也认识到不足,之后果断改进,做出了如下声明:JavaScript语法禁止表达式语句以大括号或关键字"function"开头。
知错能改善莫大焉,当知道javascript做出如此强制的规约时,就一下子对前面两个疑惑有了答案。
在这之前,我们还要想提下三个概念:语句上下文、表达式上下文和表达式语句。
语句上下文:在这个环境中,这这句代码(表达式或者语句)应该理解成一个语句。
表达式上下文:在这个环境中,这句代码(表达式或者语句)应该理解成一个表达式。
表达式语句:这个表达式既可以看作是一个表达式(因为它能产生一个值),又可以看作是一个执行语句(因为它能执行某些功能,比如执行一个函数等)。表达式语句可以是javascript链式编程的基础。
上面这个概念起辅助理解作用,不用做过深追究。
我们再来看之前的那两个疑惑:
第一个,vloop的冒号后面由大括号中那一段代码,里面都有循环和赋值等操作,那说明它都不是一个表达式语句,所以它不必遵循上面的规定。在 这其实它只是一个代码块语句而已。不过对于对象字面量而言,它确实一个货真价实的表达式语句,根据规约,它就只能乖乖的做表达式,不能做语句。
第二个,对于NFE类型函数来说,你可以将它看作是一个函数申明语句,同时也可以将之看成一个表达式,但是根据javascript的规定,表 达式语句不能以function开头,所有在这,NFE中的肯定是表达式了。当然,对于FD,这个很明显,是函数声明语句,不用怀疑。
其实,还有另一种判定方法,根据上下文判断,利用之前我们说过语句上下文和函数上下文。对于一个表达式语句,当你无法区分它是表达式还是语句, 你参照上下文,判断程序在这需要做什么,是变量赋值?还是语句执行?看到前面由“=”(赋值)或者用“()”(小括号,在这时分组符,里面只能包含表达 式),你就可以肯定,这是一个表达式上下文。javascript的解释器就是这个干的。
var foo = function _foo(index){ console.log("传入的参数是:"+index||"空值") }(1); //输出:传入的参数是:1 console.log(foo); //输出:undefined //根据上下文判断,"var foo = "后面是表达式上下文,所有解释器自动将后面看成一个立即执行函数,虽然没有小括号。 function foo(index){ console.log("传入的参数是:"+index||"空值") }(1) //输出:1 console.log(foo); //function foo(index){...} //解释器判断此为语句上下文,所以讲语句拆分为两段。前一段为函数声明,后一段“(1)”为一个简单的分组语句。
看到上面,你是不是灵机一动,发现你居然可以强制将表达式语句转换成表达式了!
转换方法:
(1)利用小括号,也就是分组符号(分组符内只允许表达式),进行转换。
VAR O; O =評価( "{OBJ: 'このオブジェクトである'}") はconsole.log(O)//これは、対象となる 評価= O( "({OBJ: 'このオブジェクトである'})") はconsole.log(O)//オブジェクト{OBJ:「このオブジェクトです」}
前者は、実行時に、evalの括弧を追加していない文字列リテラルに割り当てられているOので、文の実行とみなされ、後者は入れ括弧であるとみなされ、すべてのリターン、式のコンテキストで実行されていると考えられますオブジェクト。
(2)演算子を使用したJavaScriptエンジンが、それは式である必要があり、操作に関与していることだと思いますので。
関数+(インデックス){ にconsole.log( "着信パラメータがある:" +インデックス|| "NULL"); インデックスを返す; }(1) //出力:受信パラメータである:1つの //式結果は次のとおりです。1
私はまた、上記のコードは、この文を介して実行される覚えはなく、フロントではあまりプラス記号(「+」)でした。2の結果を比較してください。