語句塊是什么?
其實就是用 {} 包裹的一些js代碼而已,當然語句塊不能獨立作用域。
可以詳細參見這里《MDN block》
也許很多人第一印象 {} 不是對象字面量么?怎么成了語句塊了?
如果在賦值語句或者表達式里用的時候,確實是對象字面量,如:
var a = {}; ({toString:function(){return "hehe"}}) + "...";
是不是很有意思。。
但是直接使用如:
{toString: function(){return "hehe"}}
卻不能正常執行
其實這里的 {} 只是起到語句塊的作用,而不是對象字面量。
怎么回事呢,明明就是對象啊。。
其實這里要說到標簽了。
我簡單描述下標簽是什么,如果想詳細了解,請移步 《MSN label》
我是標簽: var a = 1;
一切正常,從 MSN label 里可以看到,標簽往往是結合 continue, break 一起使用的。
知道標簽是什么了,就可以回到剛才的問題上了。
{toString: function(){return "hehe"}} 其實就是
{ // 語句塊 標簽: function(){return "hehe"} }
由於 function(){return "hehe"} 既不是函數聲明,也不是函數表達式,所以就報錯了。
我們只要簡單修改下,修改成函數聲明或者函數表達式即可。
{ // 語句塊 標簽1: function test1(){return "hehe"}; 標簽2: var test2 = function(){return "hehe"}; }
可以看到一切正常,這個就是語句塊和標簽
它可以構成非常像對象字面量的語句,但其實它仍然是 語句塊 + 標簽 而已。
還記不記得你用 eval 解析 json 的時候,不加 () 就報錯么。
其實現在非常容易解釋了,因為當直接執行 {} 的時候,只把內部代碼當作語句塊執行,而不是對象字面量。
加上 () 就是讓它當作表達式執行,所以才能正常解析成對象字面量。
這也是上面這個 ({toString:function(){return "hehe"}}) + "..."; 必須加 () 的原因。
其實你完全可以這樣寫你的代碼:
程序猿A寫的功能塊: { // 功能塊代碼... } 程序猿B寫的功能塊: { // 功能塊代碼... }
這樣是不是很清晰?
但是不推薦這樣寫,因為語句塊起不到獨立作用域的功能,所以很容易全局污染。
依然推薦
(function () { // 功能塊代碼... })();
自調用函數,不僅可以獨立作用域,還可以在 UglifyJS,Closure Compressor 等工具編譯的時候更加優化。
好了,我們來個小小的測試吧。
1. 執行 a: b: c: d: e: 1, 2, 3, 4, 5 結果是什么? 為什么? 那 a:{b:{c:1}} 呢?
2. 執行 1 + {valueOf:function(){return 1}} 結果是什么? 為什么?
好了,今天的分享就這些了,如有不對之處,請跟帖指出,小生先謝過了。