回覆列表
-
1 # 小熊社長
-
2 # 浪裡的大白條
沒有區域性作用域,只有函式作用域——在ES6裡的let關鍵字解決了這個問題。隱式型別轉換混亂,造成類似{} + []的奇怪玩法,以及==運算子的隱患instanceof運算子混亂,且對於自己模擬繼承實現的型別系統裡表現很弱雞閉包的方便帶來的隱患,例如一個長生命函式(如事件監聽器)閉包持有一個巨大的物件,容易造成那個物件常駐記憶體(儘管可能這個函式根本沒用它)——補充一下,這個說起來簡單,其實還挺複雜的。一種典型的案例是"Detached DOM",在使用Chrome進行記憶體profiling的時候會遇到這個型別,Chrome的官方指導文件也對這個進行了非常不錯的介紹。delete運算子存在感稀薄,且容易在某些JS引擎(如V8)裡引發效能問題
1. 不適合開發大型程式
Javascript沒有名稱空間(namespace),很難模組化;沒有如何將程式碼分佈在多個檔案的規範;允許同名函式的重複定義,後面的定義可以覆蓋前面的定義,很不利於模組化載入。
2. 非常小的標準庫
Javascript提供的標準函式庫非常小,只能完成一些基本操作,很多功能都不具備。
3. null和undefined
null屬於物件(object)的一種,意思是該物件為空;undefined則是一種資料型別,表示未定義。
typeof null; // object
typeof undefined; // undefined
兩者非常容易混淆,但是含義完全不同。
var foo;
alert(foo == null); // true
alert(foo == undefined); // true
alert(foo === null); // false
alert(foo === undefined); // true
在程式設計實踐中,null幾乎沒用,根本不應該設計它。
4. 全域性變數難以控制
Javascript的全域性變數,在所有模組中都是可見的;任何一個函式內部都可以生成全域性變數,這大大加劇了程式的複雜性。
a = 1;
(function(){
b=2;
alert(a);
})(); // 1
alert(b); //2
5. 自動插入行尾分號
Javascript的所有語句,都必須以分號結尾。但是,如果你忘記加分號,直譯器並不報錯,而是為你自動加上分號。有時候,這會導致一些難以發現的錯誤。
比如,下面這個函式根本無法達到預期的結果,返回值不是一個物件,而是undefined。
function(){
return { i=1 };
}
原因是直譯器自動在return語句後面加上了分號。
function(){
return; { i=1 };
}
6. 加號運算子
+號作為運算子,有兩個含義,可以表示數字與數字的和,也可以表示字元與字元的連線。
alert(1+10); // 11
alert("1"+"10"); // 110
如果一個操作項是字元,另一個操作項是數字,則數字自動轉化為字元。
alert(1+"10"); // 110
alert("10"+1); // 101
這樣的設計,不必要地加劇了運算的複雜性,完全可以另行設定一個字元連線的運算子。
7. NaN
NaN是一種數字,表示超出瞭解釋器的極限。它有一些很奇怪的特性:
NaN === NaN; //false
NaN !== NaN; //true
alert( 1 + NaN ); // NaN
與其設計NaN,不如直譯器直接報錯,反而有利於簡化程式。
8. 陣列和物件的區分
由於Javascript的陣列也屬於物件(object),所以要區分一個物件到底是不是陣列,相當麻煩。Douglas Crockford的程式碼是這樣的:
if ( arr && typeof arr === "object" && typeof arr.length === "number" && !arr.propertyIsEnumerable("length")){
alert("arr is an array");
}
9. == 和 ===
==用來判斷兩個值是否相等。當兩個值型別不同時,會發生自動轉換,得到的結果非常不符合直覺。
"" == "0" // false
0 == "" // true
0 == "0" // true
false == "false" // false
false == "0" // true
false == undefined // false
false == null // false
null == undefined // true
" \t\r\n" == 0 // true
因此,推薦任何時候都使用"==="(精確判斷)比較符。
10. 基本型別的包裝物件
Javascript有三種基本資料型別:字串、數字和布林值。它們都有相應的建構函式,可以生成字串物件、數字物件和布林值物件。
new Boolean(false);
new Number(1234);
new String("Hello World");
與基本資料型別對應的物件型別,作用很小,造成的混淆卻很大。