建议一:防止浮点数溢出
num = 0.1+02;//0.300000000000004
这是JavaSScirpt最常报告的BUG,并且这是遵循二进制浮点数算数标准(IEEE 754)而导致的结果。
针对上面的相加可以这样进行处理:
a =(1+2)/10
建议二:慎用JavaScript类型自动转换
值 | 字符串操作环境 | 数字运算环境 | 逻辑运算环境 | 对象操作环境 |
---|---|---|---|---|
undefined | "undefined" | NaN | false | Error |
null | "null" | 0 | false | Error |
非空字符串 | 不转换 | 字符串对应的数字值 | ||
NaN | true | String | ||
空字符串 | 不转换 | 0 | false | String |
0 | “0” | 不转换 | false | String |
NaN | "NaN" | 不转换 | false | Number |
Infinity | “Infinity” | 不转换 | true | Numbery |
Number.POSITIVE_INFINITY | "Infinity" | 不转换 | true | Number |
Number.NEGATIVE_INFINITY | “Infinity” | 不转换 | true | Number |
Number.MAX_VALUE | "1.7976931348623157e+308" | 不转换 | true | Number |
Number.MIN_VALUE | "5e-324" | 不转换 | true | Number |
其他所有数字 | “数字的字符串值” | 不转换 | true | Number |
true | "true" | 1 | 不转换 | Boolean |
false | "false" | 0 | 不转换 | Boolean |
对象 | toString() | valueOf() 或 toString()或NaN | true | 不转换 |
建议三:正确检测数据类型
使用typeof运算符返回一个用于识别其运算数类型的字符串。对于任何变量来说,使用typeof运算符总是以字符串的形式返回以下6种类型之一:
“number”
“string”
“boolean”
“function”
“undefined”
不幸的是,在使用typeof检测null值时,返回的是“object”,而不是“null”。更好的检测null的方式其实很简单。下面定义一个检测值类型的一般方法:
function type(o){
return (o===null) ? "null" : (typeof o);
}
这样就可以避开因为null值影响基本数据的类型检测。注意: typeof不能够检测复杂的数据类型,以及各种特殊用途的对象,如正则表达式、日期对象、数学对象等。
对于对象和数组,可以使用constructor属性,该属性引用的是原来构造该对象的函数。如果结合typeof运算符和constructor属性,基本能够完成数据类型的检测。
值(value) | typeof value(表达式返回值) | value.constructor(构造函数的属性值) |
---|---|---|
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属性可以判断绝大部分数据的类型。但是,对于 undefined和null特殊值,就不能用constructor属性,因为使用JavaScript解释器就会抛出异常。此时,可以先把值转换为布尔值,如果为true,则说明不是undefined和null值,然后再调用constructor属性,例如:
var value=undefined;
alert(typeof value);
alert(value && value.constructor);
var value=null;
alert(typeof value);
alert(value && value.constructor);
对于数值直接量,也不能使用constructor属性,需要加上一个小括号,这是因为小括号运算符能够把数值转换为对象,例如:
alert((10).constructor)
使用toString方法检测对象类型是最安全,最准确的。调用toString()方法把对象转化为字符串,然后通过检测字符串中是否包含数组所持有的标志字符可以确定对象的类型。toString()方法返回的字符串形式如下:
[object class]
其中,object表示对象的通用类型,class表示对象的内部类型,内部类型的名称与该对象的构造函数名对应。
客户端JavaScript的对象和由JavaScript实现定义的其他所有对象都具有预定义的特定class值,如“Window”、“Document”和“Form”等。用户自定义对象的class值为“Object”。
class值提供的信息与对象的constructor属性值相似,但是class值是以字符串的形式提供这些信息的,而不是以构造函数的形式提供提供这些信息的,所以在特定的环境中是非常有用的。如果使用typeof运算符来检测,则所有对象的class值都为“Object”或“Function”,所以此时的class值不能够提供有效信息。
但是,要获取对象的class值的唯一方法是必须调用Object对象定义的默认toString()方法,因为不同对象都会预定义自己的toString()方法,所以不能直接调用对象的toString()方法。要调用Object对象定义的默认toString()方法,可以先调用Object.prototype.toString对象的默认toString()函数,再调用该函数的apply()方法在想要检测的对象上执行。
建议四:避免误用parseInt
parseInt是一个将字符串转换为整数的函数,与parseFloat对应,这两种函数是JavaScript的两种静态函数,用于把非数字转化为数字。
parseInt(“123abc”) //123
parseInt(“1.84”) //1 小数对于它来说是非法字符
parseInt(“.123”) //NaN 代表它不是数字
parseInt可以将字符串转换为数字,但需要做基数处理。
parseInt(“08”,10) //10是它的基数,在对日期类型处理时要注意 结果为8
我认为,用正则做匹配可能更好一点
建议五:防止JavaScript自动插入分号
JavaScript解析时,能够在一句话后面自动插入一个分号,用来修饰语句末尾遗漏的分号分隔符。例如:
var f = function(){
return
{
sratus: true
};
}
此时,JavaScript的解析机制使让它返回了undefined,从而导致下面正真要返回的对象被忽略。
建议六:正确处理JavaScript特殊值
1.正确使用NaN和Infinity
NaN是IEEE 754中定义的一个特殊的数量值。它不表示一个数字,尽管下面的表达式返回的是true。
typeof NaN === 'number' //true
下面的结果令人惊讶:
NaN === NaN //false
NaN !== NaN //true
为了方便检测NaN值,JavaScript提供了isNaN静态函数,以辨别数字与NaN区别。
isNaN(NaN) //true
isNaN(0) //false
isNaN('oops') //true
isNaN('0') //false
判断一个值是否可用做数字的最佳方法是使用isFinte函数,因为它会筛除掉NaN和Infinity。Infinity表示无穷大。当数值超过浮点数所能够表示的范围时,就要用Infinity表示。反之,负无穷大为-Infinity。
判断一个值是否可以用来做数字用isFinite函数,因为会筛除掉NaN和Infinity。Infinity表示无穷大。当数值超过浮点数所能表示的范围时,就要使用Infinity表示。反之,负无穷大为-Infinity。
使用isFinite函数能够检测NaN,正负无穷大。如果是有限数字返回true,否则返回false。
建议七:小心保留字的误用
要注意在不同浏览器中对保留字的限制也不同
建议八:谨慎使用运算符
1.用===,而不用==
如果两个运算符的类型一致且拥有相同的值,那么===返回true,而 !== 返回false。
==和 != 只有在两个运算数类型一致时才做出正确的判断,如果两个运算符是不同的类型,会试图强制转换运算数的类型。转换规则如下:
'' == '0' //false
0 == '' //true
0 == '0' //true
false == 'false' //false
false == '0' //true
false == undefined //false
false == null //false
null == undefined //true
2.谨慎使用++和--
递增(++) 和递减(--)运算符使程序员可以用非常简洁的风格去编码,但大多数缓冲区溢出错误所造成的漏洞都是由这种编码导致的。
3.小心逗号运算符
逗号在JavaScript语言中表示连续运算,并返回最后运算的结果。
var a = (1, 2, 3, 4)
alert(a); //4
alert((a=1, 2, 3, 4)) //4
alert(a=(1, 2, 3, 4)) //4
4.警惕运算符的副作用
var a;
a=1;
网友评论