判true和false狀況javascript
true:已定義的空對象、「false」、非0數字、已定義的空數組。java
false:數字0、NaN、null、undefined、空字符串。jquery
三種全局變量程序員
全部函數外聲明變量、window.test方式(window是全局對象)、不帶var的變量。算法
有個大坑:undefined和NaN居然也是全局變量,而且咱們能夠修改其值。
json
做用域問題數組
其餘語言都是一對花括號是一個做用域,此做用域中的變量對於外部是不可見的。js雖然也有做用域,也是用花括號包起來,可是:此做用域中聲明的變量在包含此做用域的函數在任何位置都是可見的(閉包是典型的例子)。簡單例子:瀏覽器
var test = {安全
a: "a",閉包
b: function(){} //在b函數中對啊是可見的,不管b函數出如今整個函數的任何地方都如此
}
智能補充分號
js有智能補充分號功能,倒是個雞肋功能(做爲程序員,寫完一個語句順手分號是必備技能吧~)。簡單例子:
return
{
a: "a"
}
會被識別爲:
return ; //返回值變成了undefined
{
a: "a"
}
正確的應該這樣寫:
return{
a: "a"
}
保留字用在其餘地方
保留字原本不該該用來做爲鍵值的(做爲變量和參數是絕對不能夠的),可是非要用也何嘗不可(建議不要這麼用):
var class; //非法
var test = {case: "hehe"}; //非法,在最新的幾個瀏覽器中變得不非法了,仍是強烈建議避免這樣用。
var test = {"case": "hehe"}; //OK
test.case = "xixi"; //非法
test["case"] = "xixi"; //OK
typeof問題
不能識別null,typeof null 返回的居然是「object」而不是「null」。
而且typeof /a/ 返回的也是「object」或者「function」而不是「regexp」。
typeof還不能識別array,由於js沒有真正的數組,所謂的數組實際上是一個鍵值爲數字的鍵值對/對象/json。
要檢測一個變量(value)是否是數組能夠這樣:Object.prototype.toString.apple(value) === "[object Array]"
NaN問題
NaN不是一個具體的變量或者數值,它是「number」可是沒有具體的值,每次生成的數值都不同。
typeof NaN === "number" //true
NaN === NaN //false
NaN !== NaN //true
可能出現NaN的狀況:試圖把非數字形式的字符串轉換爲數字,例如:
+"123" //123
+"test123" //NaN
isNaN函數:
isNaN(NaN) //true
isNaN(0) //false
isNaN("test123") //true
isNaN("123") //false
判斷一個值(value)是不是number或者能夠轉爲number的字符串,能夠這樣:typeof value === "number" && isFinite(value)
parseInt安全用法
衆所周知這個函數是用來把字符串轉換成整數,可是在遇到沒法轉換的字符時會中止轉換而不報任何的錯誤,例如:parseInt("123")和parseInt("123 a")結果都是123。
強烈建議如此使用:parseInt("value",10) //10表示基數參數,十進制
hasOwnProperty漏洞
hasOwnProperty是對象的一個方法,而不是一個運算符,因此咱們能夠修改這個方法,從而覆蓋了默認的方法,再次調用hasOwnProperty時就中招了~~~
對象的隱藏屬性
例如:var test = {}
別覺得test對象裏沒用任何東西哦~~~咱們每每會這樣認爲,從而忽略了Object.prototype這個原型鏈上包含着一個名爲constructor的成員對象屬性~~~
so,遍歷對象必定要加倍當心(儘可能避免遍歷對象,能用array代替最好),結合typeof和hasOwnProperty能夠避免隱含危險。
==和===
強烈建議:使用===和!== 代替 == 和 !=
由於不一樣類型比較,==在判斷時會試圖強制轉換類型後比較,在轉換類型過程當中隱藏危險太多太複雜了。例如:
"" == "0" //false
"" == 0 //true
0 == "" //true
0 == "0" //true
false == "false" //false
false == "0" //true
false == 0 //true
false == undefined //false
false == null //false
null == undefined //true
"\t\n\r" == 0 //true
"\t\n\r" == "" //false
"\t\n\r" == null //false
以上例子若是改用===,所有爲false。
在程序員的世界,x==y,y==z,那麼x==z。可是,js卻違背了這種傳遞性,改成===則遵循。
不應存在的with語句
強烈建議:任什麼時候候都不要使用js的with語句。
雖然with語句簡短,可是with語句可讀性及其差,檢查bug時會讓你發而且瘋,阻斷了變量名的詞法做用域綁定致使處嚴重影響js處理器的速度。
continue語句
都知道,用來跳出循環~~~網友測試,經過重構移除continue語句以後,性能會獲得必定的改善。so,儘可能避免使用continue語句吧~~~
function語句和表達式
第一種:function test(){}
第二種:var test = function(){}
第三種:var test = function test(){}
建議使用第二種,由於第一種function不管放在哪,都會並定義到所在做用域的頂層,沒有了先聲明後定義/使用的規範了。舊版的瀏覽器在if語句中不容許使用function語句,新版的不少居然容許了,我擦~~~具體哪一個瀏覽器哪一個版本沒去詳細測試。
new的利弊
new是其餘語言(如java)用於實例化類對象的關鍵字,感受高大上~~~可是js裏最好避免使用,請看:
var test = new String("hehe");
var test = new Array("a","b")
這些大能夠用
var test = 「hehe」;
var test = ['a','b'];
代替,何須用new呢。相似的Boolean、Number和Object都是。
可是在實例化咱們本身寫的類的時候,又必須使用new(把新對象綁定給this),不然this會被綁定到全局對象,對象的屬性就是全局的,污染全局變量。這種狀況不是語法錯誤也不是邏輯錯誤,在編譯已經運行時都不會報錯,查bug就是一個無底洞~~~
建議:須要new的類名都使用大寫開頭,畢竟業內習慣類名都是以大寫字母開頭。
void爲什麼物
void在其餘語言中是一種類型,表示值爲空。可是,在js裏void是一個運算符,接受一個運算數並返回undefined,典型用法是:javascript:void(0),在href中阻斷跳轉。可是這個不是標準的用法,沒有什麼意義,應該避免去使用它。
避免使用位運算
位運算速度很是之快,可是個人理解是依靠硬件直接處理,可是js的執行環境接觸不到硬件,也沒法控制硬件,因此最好避免使用。而且位運算中的 & 和 | 等符號和 && 和 || 符號較爲類似,容易誤寫以及減低可讀性,特別是查bug的時候會有想死的感受。
萬惡的小數(任什麼時候候都要想辦法去避免處理小數)
js對於小數的處理存在無數的bug,因此咱們任什麼時候候須要處理小數的話最好都要轉化爲整數來處理,不然會出現意想不到的結果。目前我親測發現是有如下這些:
0.1+0.2 //不是等於0.3,而是0.30000000000000004
0.07*100 //不是等於7,而是7.000000000000001
a = 3;b = 3.000000000000001;a == b爲true,由於計算機自己沒法存儲小數,都是以模擬的形式存儲的。
js對象的拷貝,java有clone方法,而js卻沒有須要本身寫代碼實現(代碼參照《Node.js開發指南》一書第163頁),其中分爲淺拷貝和深拷貝,淺拷貝原理就是循環遍歷全部屬性中的基本類型(不包括對象類型)屬性,假如屬性是一個對象類型就須要用深拷貝了。深拷貝的原理就是用遞歸來遍歷,遇到複雜的對象類型同樣能夠勝任,可是遇到互相引用的對象就連淺拷貝和深拷貝都沒轍了。遇到互相引用的對象,須要拷貝時,就必須設計一套圖論算法,分析對象之間的依賴關係,創建一個拓撲結構圖,而後分別依次複製每一個頂點,並從新構建它們之間的依賴關係。
jquery的attr和prop的區別
對於HTML元素自己就帶有的固有屬性,在處理時,使用prop方法。
對於HTML元素咱們本身自定義的DOM屬性,在處理時,使用attr方法。
例如:在寫全選和取消全選時,寫法以下
$("thead input").click(function(){ if ($(this).is(':checked')) { $("tbody input").prop("checked",true); //假如用attr,則點擊全選→取消小全選→再點擊全選就無效了。 }else{ $("tbody input").prop("checked",false); } });