也不是閑着沒事去看壓縮代碼,但今天調試自己代碼的時候發現有點意思。因為是自己寫的,雖然壓縮了,格式化之后還是很好辨認。當然作為min的首要准則不是可讀性,而是精簡。那么它會盡量的縮短代碼,盡量的保持一行,最大化的減少的空白。我們常用的分號都會被替換成了逗號,短句變成了連貫的長句。
1.立即執行函數

我本是第二種寫法,uglify給我替換成了第一種(當然更短一點)。其實括號和!號的作用都是將funtion的部分轉成一個表達式,而不再是申明。這樣就能立即執行,同理~ +都可以做到。
2.變量名替換
這個是自然的,函數名、參數名、變量名都替換成了單個字母。甚至是‘_’
3.函數置頂
function foo (){} 這種形式的代碼都會被放到模塊的最頂端。當然這是一種規范,后來發現還有另外一個作用就是方便后面的代碼合並。 比如 我們這樣定義:
var self=this; function a(){} self.a=a; function b(){} self.b=b; return self;
會替換成:
function a(){} function b(){} var s={} return s.a={},s.b={},s
注意到最后的s 不能漏了,return會以最后一個表達式的結果為准。
function rt(n) { return n; } function xx() { return rt(1), rt(2); }
執行xx()得到的是2,如果 rt(2)后面還有個不返回值的函數執行,那么xx()會得到undefined。
4.bool值替換
false-->!1 true-->!0
5.if
if語句是壓縮最多的地方。
1) return 前置:
function load() { if (t) { x = false; log("error"); return; } console.log("22") }
比如我的原函數大概是這樣。壓縮后成了這樣:
if (t) return x =!1,void log("error")
return提前了,末尾多了一個void。 這是為什么呢。 沒有大括號,if的四段代碼變成了一句話。void的在這里的作用是抹掉函數的返回值。因為本來的這個if 是沒有返回值的 。如果這個時候log方法帶有返回值。那么調用load就會拿到這個返回值。這會產生干擾,違背了原函數的本意。所以用void抹掉了。
2) 短路
function foo() { if (!x) { return; } console.log("doA"); console.log("doB"); }
壓縮后:
function f() { x || console.log("doA"), console.log("doB"); }
這樣蠻不錯的。同理:
if(x&&y){
doa();
dob();
}
doc();
--> x&&y&&(doa(),dob()),doc()
原本四行變成了一行代碼。
3).為了合並一行,這也行:
console.log("doA"); console.log("doB"); if (x>0) { console.log("true"); }
合並成這樣:
if (console.log("doA"), console.log("doB"), x > 0) console.log("true");
平時這么寫可能不太友好,重點是在if語句中,最后一句才是判斷句。結合之前的return。想必對逗號語句有了深刻的認識。
4)throw也不放過
if (errMsg) { util.triggerCallback(fail, "模型驗證錯誤"); throw Error(errMsg); }
壓縮后:
if (a) throw x.triggerCallback(o, "模型驗證錯誤"), Error(a)
調換了語句的順序,把throw看成return 就明白了。
5) if else
這個會替換成三元表達式 a?b:c 。
6.數字處理
整百整千的會處理成科學計數 1000 -->1e3 。
7. while
var offset = 0; while (true) { if (offset >= bufferLength) { break; } }
會替換成這樣:
for (var n = 0; ; ) { if (n >= K) break }
確實不錯,節省了一行代碼。
以上只是獨自對比自己的代碼發現的一些東西,有的可以在平時的編碼中用起來,當然不是追求所有代碼都寫成一行,這樣可讀性比較差,另外可能你下次看壓縮代碼就不那么費勁了。歡迎補充。