建議一:防止浮點(diǎn)數(shù)溢出
num = 0.1+02;//0.300000000000004
這是JavaSScirpt最常報(bào)告的BUG,并且這是遵循二進(jìn)制浮點(diǎn)數(shù)算數(shù)標(biāo)準(zhǔn)(IEEE 754)而導(dǎo)致的結(jié)果秋泄。
針對(duì)上面的相加可以這樣進(jìn)行處理:
a =(1+2)/10
建議二:慎用JavaScript類型自動(dòng)轉(zhuǎn)換
值 | 字符串操作環(huán)境 | 數(shù)字運(yùn)算環(huán)境 | 邏輯運(yùn)算環(huán)境 | 對(duì)象操作環(huán)境 |
---|---|---|---|---|
undefined | "undefined" | NaN | false | Error |
null | "null" | 0 | false | Error |
非空字符串 | 不轉(zhuǎn)換 | 字符串對(duì)應(yīng)的數(shù)字值 | ||
NaN | true | String | ||
空字符串 | 不轉(zhuǎn)換 | 0 | false | String |
0 | “0” | 不轉(zhuǎn)換 | false | String |
NaN | "NaN" | 不轉(zhuǎn)換 | false | Number |
Infinity | “Infinity” | 不轉(zhuǎn)換 | true | Numbery |
Number.POSITIVE_INFINITY | "Infinity" | 不轉(zhuǎn)換 | true | Number |
Number.NEGATIVE_INFINITY | “Infinity” | 不轉(zhuǎn)換 | true | Number |
Number.MAX_VALUE | "1.7976931348623157e+308" | 不轉(zhuǎn)換 | true | Number |
Number.MIN_VALUE | "5e-324" | 不轉(zhuǎn)換 | true | Number |
其他所有數(shù)字 | “數(shù)字的字符串值” | 不轉(zhuǎn)換 | true | Number |
true | "true" | 1 | 不轉(zhuǎn)換 | Boolean |
false | "false" | 0 | 不轉(zhuǎn)換 | Boolean |
對(duì)象 | toString() | valueOf() 或 toString()或NaN | true | 不轉(zhuǎn)換 |
建議三:正確檢測(cè)數(shù)據(jù)類型
使用typeof運(yùn)算符返回一個(gè)用于識(shí)別其運(yùn)算數(shù)類型的字符串册着。對(duì)于任何變量來(lái)說(shuō)斟冕,使用typeof運(yùn)算符總是以字符串的形式返回以下6種類型之一:
“number”
“string”
“boolean”
“function”
“undefined”
不幸的是荧琼,在使用typeof檢測(cè)null值時(shí)丽惶,返回的是“object”炫七,而不是“null”。更好的檢測(cè)null的方式其實(shí)很簡(jiǎn)單钾唬。下面定義一個(gè)檢測(cè)值類型的一般方法:
function type(o){
return (o===null) ? "null" : (typeof o);
}
這樣就可以避開因?yàn)閚ull值影響基本數(shù)據(jù)的類型檢測(cè)诉字。注意: typeof不能夠檢測(cè)復(fù)雜的數(shù)據(jù)類型,以及各種特殊用途的對(duì)象知纷,如正則表達(dá)式壤圃、日期對(duì)象、數(shù)學(xué)對(duì)象等琅轧。
對(duì)于對(duì)象和數(shù)組伍绳,可以使用constructor屬性,該屬性引用的是原來(lái)構(gòu)造該對(duì)象的函數(shù)乍桂。如果結(jié)合typeof運(yùn)算符和constructor屬性冲杀,基本能夠完成數(shù)據(jù)類型的檢測(cè)。
值(value) | typeof value(表達(dá)式返回值) | value.constructor(構(gòu)造函數(shù)的屬性值) |
---|---|---|
var value=1 | "number" | Number |
var value="a" | "string" | String |
var value=true | "boolean" | Boolean |
var value={} | "object" | Object |
var value=new Object() | "object" | Object |
var value=[] | "object" | Array |
var value=new Array() | "object" | Array |
var value=function(){} | "function" | Function |
function className(){}; | "object" | className |
使用constructor屬性可以判斷絕大部分?jǐn)?shù)據(jù)的類型睹酌。但是权谁,對(duì)于 undefined和null特殊值,就不能用constructor屬性憋沿,因?yàn)槭褂肑avaScript解釋器就會(huì)拋出異常旺芽。此時(shí),可以先把值轉(zhuǎn)換為布爾值辐啄,如果為true采章,則說(shuō)明不是undefined和null值,然后再調(diào)用constructor屬性壶辜,例如:
var value=undefined悯舟;
alert(typeof value);
alert(value && value.constructor);
var value=null;
alert(typeof value);
alert(value && value.constructor);
對(duì)于數(shù)值直接量,也不能使用constructor屬性砸民,需要加上一個(gè)小括號(hào)抵怎,這是因?yàn)樾±ㄌ?hào)運(yùn)算符能夠把數(shù)值轉(zhuǎn)換為對(duì)象奋救,例如:
alert((10).constructor)
使用toString方法檢測(cè)對(duì)象類型是最安全,最準(zhǔn)確的反惕。調(diào)用toString()方法把對(duì)象轉(zhuǎn)化為字符串菠镇,然后通過(guò)檢測(cè)字符串中是否包含數(shù)組所持有的標(biāo)志字符可以確定對(duì)象的類型。toString()方法返回的字符串形式如下:
[object class]
其中承璃,object表示對(duì)象的通用類型利耍,class表示對(duì)象的內(nèi)部類型,內(nèi)部類型的名稱與該對(duì)象的構(gòu)造函數(shù)名對(duì)應(yīng)盔粹。
客戶端JavaScript的對(duì)象和由JavaScript實(shí)現(xiàn)定義的其他所有對(duì)象都具有預(yù)定義的特定class值隘梨,如“Window”、“Document”和“Form”等舷嗡。用戶自定義對(duì)象的class值為“Object”轴猎。
class值提供的信息與對(duì)象的constructor屬性值相似,但是class值是以字符串的形式提供這些信息的进萄,而不是以構(gòu)造函數(shù)的形式提供提供這些信息的捻脖,所以在特定的環(huán)境中是非常有用的。如果使用typeof運(yùn)算符來(lái)檢測(cè)中鼠,則所有對(duì)象的class值都為“Object”或“Function”可婶,所以此時(shí)的class值不能夠提供有效信息。
但是援雇,要獲取對(duì)象的class值的唯一方法是必須調(diào)用Object對(duì)象定義的默認(rèn)toString()方法矛渴,因?yàn)椴煌瑢?duì)象都會(huì)預(yù)定義自己的toString()方法,所以不能直接調(diào)用對(duì)象的toString()方法惫搏。要調(diào)用Object對(duì)象定義的默認(rèn)toString()方法具温,可以先調(diào)用Object.prototype.toString對(duì)象的默認(rèn)toString()函數(shù),再調(diào)用該函數(shù)的apply()方法在想要檢測(cè)的對(duì)象上執(zhí)行筐赔。
建議四:避免誤用parseInt
parseInt是一個(gè)將字符串轉(zhuǎn)換為整數(shù)的函數(shù)铣猩,與parseFloat對(duì)應(yīng),這兩種函數(shù)是JavaScript的兩種靜態(tài)函數(shù)茴丰,用于把非數(shù)字轉(zhuǎn)化為數(shù)字达皿。
parseInt(“123abc”) //123
parseInt(“1.84”) //1 小數(shù)對(duì)于它來(lái)說(shuō)是非法字符
parseInt(“.123”) //NaN 代表它不是數(shù)字
parseInt可以將字符串轉(zhuǎn)換為數(shù)字,但需要做基數(shù)處理较沪。
parseInt(“08”,10) //10是它的基數(shù)鳞绕,在對(duì)日期類型處理時(shí)要注意 結(jié)果為8
我認(rèn)為,用正則做匹配可能更好一點(diǎn)
建議五:防止JavaScript自動(dòng)插入分號(hào)
JavaScript解析時(shí)尸曼,能夠在一句話后面自動(dòng)插入一個(gè)分號(hào),用來(lái)修飾語(yǔ)句末尾遺漏的分號(hào)分隔符萄焦。例如:
var f = function(){
return
{
sratus: true
};
}
此時(shí)控轿,JavaScript的解析機(jī)制使讓它返回了undefined冤竹,從而導(dǎo)致下面正真要返回的對(duì)象被忽略。
建議六:正確處理JavaScript特殊值
1.正確使用NaN和Infinity
NaN是IEEE 754中定義的一個(gè)特殊的數(shù)量值茬射。它不表示一個(gè)數(shù)字鹦蠕,盡管下面的表達(dá)式返回的是true。
typeof NaN === 'number' //true
下面的結(jié)果令人驚訝:
NaN === NaN //false
NaN !== NaN //true
為了方便檢測(cè)NaN值在抛,JavaScript提供了isNaN靜態(tài)函數(shù)钟病,以辨別數(shù)字與NaN區(qū)別。
isNaN(NaN) //true
isNaN(0) //false
isNaN('oops') //true
isNaN('0') //false
判斷一個(gè)值是否可用做數(shù)字的最佳方法是使用isFinte函數(shù)刚梭,因?yàn)樗鼤?huì)篩除掉NaN和Infinity肠阱。Infinity表示無(wú)窮大。當(dāng)數(shù)值超過(guò)浮點(diǎn)數(shù)所能夠表示的范圍時(shí)朴读,就要用Infinity表示屹徘。反之,負(fù)無(wú)窮大為-Infinity衅金。