天天看點

【JS】表達式&語句

1.語句和表達式

JavaScript中的表達式和語句是有差別的.一個表達式會産生一個值,它可以放在任何需要一個值的地方,比如,作為一個函數調用的參數.下面的每行代碼都是一個表達式:

myvar
 + x
myfunc("a", "b")
           

語句可以了解成一個行為.循環語句和if語句就是典型的語句.一個程式是由一系列語句組成的.JavaScript中某些需要語句的地方,你可以使用一個表達式來代替.這樣的語句稱之為表達式語句.但反過來不可以:你不能在一個需要表達式的地方放一個語句.比如,一個if語句不能作為一個函數的參數.

2.其他文法

看看下面這兩對類似的文法,搞懂這些後,能夠幫助我們更好的了解語句和表達式之間的關系.

2.1 if 語句和條件運算符

下面是一個if 語句的例子:

var a ;
if ( b >=  ) 
{
    a = b ;
}
else
{
    a = -b ;
}
           

類似if語句功能的表達式叫做條件運算符.上面的語句等價于下面的.

var a = ( b >=     ?   b   :   -b ) ;
           

在等于号=和分号;之間的代碼就是條件表達式.兩邊的小括号不是必需的,但我覺得小括号能讓條件表達式更易讀.

2.2 分号和逗号運算符

在JavaScript中,使用分号可以連接配接兩個語句:

要想連接配接兩個表達式,使用的是不常見的逗号運算符:

逗号運算符會計算前後兩個表達式,然後傳回右邊表達式的計算結果.例如:

> "a", "b"
'b'

> var x = ("a", "b");
> x
'b'

> console.log( ( "a", "b" ) );
b
           

3.看似語句的表達式

一些表達式看起來像是語句,這可能會帶來一些麻煩.

3.1 對象字面量和語句塊

下面是一個對象字面量,也就是一個可以生成一個對象值的表達式.

{
    foo : bar( ,  )
}
           

不過同時,它也是一個完全合法的語句,這個語句的組成部分有:

  • 一個代碼塊:一個由大括号包圍的語句序列.
  • 一個标簽:你可以在任何語句前面放置一個标簽.這裡的foo就是一個标簽.
  • 一條語句:表達式語句bar( 3, 5 ).

你也許會感到震驚,那就是JavaScript居然可以有獨立的代碼塊(常見的代碼塊是依托于循環或者if語句的).下面的代碼示範了這種代碼塊的作用:你可以給它設定一個标簽然後跳出這個代碼塊.

function test ( boolean ) 
{
    printing: {
        console.log("One");
        if ( !boolean ) break printing;
        console.log("Two");
    }
    console.log("Three");
}

> test(false)
One
Three

> test(true)
One
Two
Three
           
3.2 函數表達式和函數聲明

下面的代碼是一個函數表達式:

function ( ) {   }
           

你還可以給這個函數表達式起一個名字,将它轉變為一個命名(非匿名)的函數表達式:

function foo( ) {    }
           

這個函數的函數名( foo )隻存在于函數内部,比如,可以用它來做遞歸運算:

> var fac = function me(x) { return x <=  ?  : x * me(x-) }
> fac()

> console.log(me)
ReferenceError: me is not defined
           

一個命名的函數表達式從表面上看起來,和一個函數聲明并沒有什麼差別.但他們的效果是不同的:一個函數表達式産生一個值(一個函數).一個函數聲明執行一個動作:将一個函數指派給一個變量. 此外,隻有函數表達式可以被立即調用,函數聲明不可以.

3.3 解決沖突

從3.1和3.2可以看出,有些表達式和語句在表面上看不出有什麼差別.也就意味着,相同的代碼,出現在表達式上下文和出現在語句上下文會表現出不同的作用.通常情況下,這兩種上下文是沒有交集的.但是,如果是表達式語句的話,會有一個重疊:也就是說,會有一些表達式出現在語句上下文上.為了解決這種歧義,JavaScript文法禁止表達式語句以大括号或關鍵字”function”開頭:

ExpressionStatement :
    [lookahead ∉ {"{", "function"}] Expression ;
           

那麼,如果你想寫一個以那些标志開頭的表達式語句,該怎辦呢? 你可以把它放在一個括号内部,這樣并不會改變運作結果,隻會確定該表達式被解析在表達式上下文中.讓我們看兩個例子.第一個例子:eval會按照語句上下文解析它的參數.如果你想讓eval傳回一個對象,你必須在對象字面量兩邊加上一個括号.

> eval( "{ foo:  }" )
123
> eval( "({ foo:  })" )
{ foo:  }
           

第二個例子:下面的例子是一個立即執行的函數表達式.

> (function ( ) { return "abc" } ( ))
'abc'
           

如果你省略了小括号,你會得到一個文法錯誤(函數聲明不可以是匿名的):

> function ( ) { return "abc" }( )
SyntaxError: function statement requires a name
           

如果你添加上函數名,還會得到一個文法錯誤(函數聲明不能被了解執行):

> function foo( ) { return "abc" } ( )
SyntaxError: syntax error
           

另外一個能讓表達式在表達式上下文上被解析的辦法是使用一進制運算符,比如 + 或者 !.但是,和使用括号不同的是,這些操作符會改變表達式的運作結果.如果你不關心結果的話,完全可以使用:

> +function ( ) { console.log("hello") } ( )
hello
NaN
           

NaN是+作用在函數執行後的傳回值undefined上的結果.

【JS】表達式&amp;語句

轉載位址:http://www.cnblogs.com/ziyunfei/archive/2012/09/16/2687589.html

繼續閱讀