--總結來自:《javascript語言精粹》
任何語言都有其優美的地方和其雞肋的地方。避歸一些語言的糟粕,能相應的下降bug出現的概率。
優美處:
函數是頭等對象
基於原型繼承的動態對象
對象字面量和數組字面量
糟粕:
1. 全局變量
全局變量有三種表達方式:
var聲明:var foo = value;
添加屬性到全局對象上,即添加到window上:window.foo = value;
未經聲明的變量:foo = value;
雖然變量能夠未經聲明就使用,可是這會致使後期的不少的bug出現,而且這些bug很難被發現。
2. 做用域
javascript中,沒有塊級做用域,代碼塊中聲明的變量在包含此代碼塊的函數的任何位置都是可見的。
因此,在js中最好的方式是在每一個函數開頭的部分聲明全部變量。
3. 自動插入分號
javascript能夠經過自動插入分號來修正有缺損的程序,可是這樣會致使不少嚴重的bug,而且不易發現。
return
{
status: true
}
上面的例子中實際返回的是undefined,由於這個值表達式的開始部分必須和return在同一行上,不在一行,js就會自動補全,致使錯誤。
正確應該以下寫法:
4.保留字
保留字即在語言中未使用,可是保留下來爲了之後可能會使用到。他們不能用來命名變量或參數。當保留字被用做對象字面量的鍵值時,他們必須被引號括起來。
1 關鍵字
break case catch continue default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with
2 保留字
abstract boolean byte char class const debugger double enum export extends fimal float goto implements import int interface long mative package private protected public short static super synchronized throws transient volatile
5. Unicoe
javascript是16位的。Unicoe把一對字符視爲一個單一的字符,而javascript認爲一對字符是兩個不一樣的字符。具體不詳...
6. typeof
typeof運算符返回一個用於識別其運算數類型的字符串。可是沒法是別null。
7. parseInt
parseInt('16')和parseInt('16 tons')結果同樣。若是字符串第一個字符是0,那麼該字符串將被基於8進制而不是10進制,因此標準的寫法是parseInt('08',10);
8. +
+ 運算符能夠用於加法運算和字符串鏈接,如何執行取決於其參數的類型。只有當兩個數都是整數型時才作加法運算。
9.浮點數
二進制的浮點數不能正確的處理十進制的小數,在javascript中,0.1 + 0.2不等於0.3。可是這個問題能夠避免。如,美圓能夠經過乘以100而所有轉成美分,而後進行加減,再將他們的和除以100來換回美圓。
10. NaN
NaN是IEEE753中定義的一個特殊的數量值。它表示的不是一個數字,可是typeof NaN === 'number'返回的是true。在代碼的轉換運算中會產生NaN,而且NaN不等於它本身。NaN出現不易排查,幸虧isNaN()能夠識別數字和NaN
11. 僞數組
javascript中沒有正真的數組,它的數組是僞數組,性能不好。
type不能辨別數組和對象,須要判斷是否爲數組,須要檢查他的constructor屬性:
if (my_value && typeof my_value === 'object' && typeof my_value.length === 'number' && !(my_value.propertyIsEnumerable('length'))) {
//my_value 確實是一個數組
}
12. 假值
javascript有一堆的假值。
如0 NaN ‘’ false null undefined辨別他們的時候要特別的當心
13. hasOwnProperty
hasOwnProperty方法被用做一個過濾器去避開for in語句的一個問題。不幸的是,hasOwnProperty是一個方法,而不是一個運算符,因此在任何對象中,他均可能會被不一樣的函數甚至一個非函數的值所替換。
14. 對象
javascript的對象不會有空對象,由於他們能夠從原型鏈中取得成員元素。而且伴隨着不少bug的出現。
雞肋:
1. ==
不要使用== 和 !=,應該使用===和!==,===和!==將兩個值的數據類型和值都進行了比較。
2. with語句
不要使用with,由於它會有bug的出現
3. eval
eval會使代碼更加難以閱讀,安全性和性能也都不太好。
4. continue語句
continue語句跳到循環的頂部。使用continue會使性能下降
5. switch貫穿
switch條件貫穿會致使其餘的問題。有用,可是很危險。
6. 缺乏的塊語句
if / while / do 和 for語句均可以接受一個括號中的代碼塊,也能夠接受單行語句。可是它模糊了程序的結構。嚴格規範並始終使用代碼塊會使得代碼更容易理解。
7. ++--
這兩個運算符容易促成一種不謹慎的編程風格。大多數的緩衝區溢出錯誤所形成的安全漏洞,都是因爲像這種編碼而致使的。
8. 位運算符
& and按位與
| or按位或
^ xor按位異或
not按位非
>> 帶符號的右移
>>> 無符號的右移
<< 左移
在大多數的語言中,這些位運算符接近於硬件處理而很是的快,在javascript中,位運算符不是硬件處理,速度很是的慢。它下降了這門語言的冗餘度,使得bug更不易被發現。
9. function 語句對比函數表達式
一個function語句就是其值爲一個函數的var語句的速記形式。function語句在解析時會發生被提高的狀況。意味着無論function被放置在哪裏,它會被移動到被定義時所在做用域的頂層。在if語句中使用function語句是被禁止的。由於大多數的瀏覽器都容許在if語句中使用function語句,但它們在解析時處理上各不相同。就形成了可移植性的問題。
10. 類型的包裝對象
new Boolean(false)
會返回一個對象,該對象有一個alueOf方法會返回被包裝的值。不要使用new Boolean/new Number / new String
避免使用new Object和new Array,可以使用{}和[]來代替。
11. new
javascript的new運算符建立一個繼承於其運算數的原型的新對象,而後調用該運算數,把新建立的對象綁定給this。在new和初始化的過程當中會出現不少的問題。最好是不去使用new。
12. void
在javascript中,void是一種運算符。無效無用費解,避免使用它。