好用的()運算子

 Mon, 12 Nov 2007 16:47:00 +0800

只是簡單的感想。算是()的妙用吧。

之前就知道用()來做出匿名函數,其實他還有更多匿名的作用。例如:

如果我要用Date物件來取開始時間與結束時間,計算開始到結束需要花費的時間,通常直覺的方法是:

var date1 = new Date();
var startTime = date1.getTime();
..........
..........
..........
var date2 = new Date();
var endTime = date2.getTime();
var duration = Math.round((endTime-startTime)/1000);

產生Date物件只是為了取得目前的timestamp,特別assign一個變數給它,似乎有一點浪費,這時候就可以用()做到匿名的效果:

var startTime = (new Date()).getTime();
..........
..........
..........
var endTime = (new Date()).getTime();
var duration = Math.round((endTime-startTime)/1000);

這樣可以少兩個變數,也少打幾個字。哈哈。

想確認一下()到底精確意義上在做什麼,不過ECMA-262還真是難以查閱......好不容易找到了他對於()的解釋:

11.1.6 The Grouping Operator
The production PrimaryExpression : ( Expression ) is evaluated as follows:
1. Evaluate Expression. This may be of type Reference.
2. Return Result(1).
NOTE This algorithm does not apply GetValue to Result(1). The principal motivation for this is so that operators such as
delete and typeof may be applied to parenthesised expressions.

嗯嗯,看起來(expression)會把括號當中的敘述grouping起來先執行,然後傳回執行的結果。不知道執行複雜的敘述會發生什麼事情呢?

.......嗚嗚,做不出可以放進()的複雜敘述,Return的意思並不是真的return什麼,而可以說是這一段敘述產生了什麼物件。例如:

alert(("this is a test").length);//就地生成一個字串物件,顯示他的長度
alert(("a"==="a").toString());//就地生成一個Boolean物件,顯示他toString函數執行的結果。

用間接的方法,可以看出()的效果:

alert(test().getTime());
function test() {
return new Date();
}

test函數會返回一個Date物件,然後我們可以直接對他操作。用()可以讓這個過程更簡單。


2007-11-18 修改

稍微複雜一點,可以用asign(=)跟三元運算子(?:)做出來。例如:

var b=0;
var a="The result is: ";
alert((a+=(b>0)? "yes":"no").length);
alert(a);

簡單地說吧,看起來雖然ECMA-262定義中限制不多,只說是(expression),但是這個expression是要可以合法地放在assignment運算子右邊的敘述。可以加上assignment運算子跟左側的identifier,但是不可以在identifier之前加var關鍵字.......所以可以放在grouping operator中的就是ECMA-262定義的AssignmentExpression囉?(java的用法好像差不多)