《编写高质量代码改善JavaScript程序的188个建议(1-78)12709.docx》由会员分享,可在线阅读,更多相关《编写高质量代码改善JavaScript程序的188个建议(1-78)12709.docx(268页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第1章 JavaScript语言基础对于任何语言来说,如何选用代码的写法和算法最终会影响到执行效率。与其他语言不同,由于JavaScript 可用资源有限,所以规范和优化更为重要。代码结构是执行速度的决定因素之一:代码量少,运行速度不一定快;代码量多,运行速度也不一定慢。性能损失与代码的组织方式及具体问题的解决办法直接相关。程序通常由很多部分组成,具体表现为函数、语句和表达式,它们必须准确无误地按照顺序排列。优秀的程序应该拥有前瞻性的结构,可以预见到未来所需要的修改。优秀的程序也有一种清晰的表达方式。如果一个程序被表达得很好,那么它更容易被理解,进而能够成功地被修改或修复。JavaScript
2、代码经常被直接发布,因此它应该自始至终具备发布质量。整洁是会带来价值的,通过在一个清晰且始终如一的风格下编写的程序会更易于阅读。JavaScrript的弱弱类型和过度度宽容特征,没没有为程序质质量带来安全全编译时的保保证,为了弥弥补这一点,我我们应该按严严格的规范进进行编码。JJavaSccript包包含大量脆弱弱的或有问题题的特性,这这些会妨碍编编写优秀的程程序。我们应应该避免JaavaScrript中那那些糟糕的特特性,还应该该避免那些通通常很有用但但偶尔有害的的特性。这样样的特性让人人既爱又恨,避避免它们就能能避免日后开开发中潜在的的错误。建议1:警惕UUnicodde乱码ECMA标准规
3、规定JavaaScrippt语言基于于Unicoode标准进进行开发,JJavaSccript内内核完全采用用UCS字符符集进行编写写,因此在JJavaSccript代代码中每个字字符都使用两两个字节来表表示,这意味味着可以使用用中文来命名名变量或函数数名,例如:1. var人名=张三三; 2. functioon睡觉(谁) 3. aleert(谁+:快睡睡觉!都半夜夜三更了。); 4. 5. 睡觉(人名);虽然ECMASScriptt v3标准准允许Uniicode字字符出现在JJavaSccript程程序的任何地地方,但是在在v1和v22中,ECMMA标准只允允许Uniccode字符符出现
4、在注释释或引号包含含的字符串直直接量中,在在其他地方必必须使用ASSCII字符符集,在ECCMAScrript标准准化之前,JJavaSccript通通常是不支持持Unicoode编码的的。考虑到JJavaSccript版版本的兼容性性及开发习惯惯,不建议使使用汉字来命命名变量或函函数名。由于JavaSScriptt脚本一般都都“寄宿”在在网页中,并并最终由浏览览器来解析和和执行,因此此在考虑到JJavaSccript语语言编码的同同时,还要顾顾及嵌入页面面的字符编码码,以及浏览览器支持的编编码。不过现现在的浏览器器一般都支持持不同类型的的字符集,只只需要考虑页页面字符编码码与JavaaScr
5、ippt语言编码码一致即可,否否则就会出现现乱码现象。当初设计JavvaScriipt时,预预计最多会有有 65 5536个字符符,从那以后后慢慢增长到到了一百万个个字符。JaavaScrript字符符是16位的的,这足够覆覆盖原有的665 5366个字符,剩剩下的百万字字符中的每一一个都可以用用一对字符来来表示。Unicodee把一对字符符视为一个单单一的字符,而而JavaSScriptt认为一对字字符是两个不不同的字符,这这将会带来很很多问题,考考虑到代码的的安全性,我我们应该尽量量使用基本字字符进行编码码。建议2:正确辨辨析JavaaScrippt句法中的的词、句和段段JavaScrri
6、pt语法法包含了合法法的JavaaScrippt代码的所所有规则和特特征,它主要要分为词法和和句法。词法法包括字符编编码、名词规规则、特殊词词规则等。词词法侧重语言言的底层实现现(如语言编编码问题等),以以及基本规则则的定义(如如标识符、关关键字、注释释等)。它们们都不是最小小的语义单位位,却是构成成语义单位的的组成要素。例例如,规范字字符编码集合合、命名规则则、标识符、关关键字、注释释规则、特殊殊字符用法等等。句法定义了语言言的逻辑和结结构,包括词词、句和段的的语法特性,其其中段体现逻逻辑的结构,句句表达可执行行的命令,词词演绎逻辑的的精髓。段落使用完整的的结构封装独独立的逻辑。在在Java
7、SScriptt程序中,常常用大括号来来划分结构,大大括号拥有封封装代码和逻逻辑的功能,由由此形成一个个独立的段落落结构。例如如,下面这些些结构都可以以形成独立的的段落。1. 2. /对象 3. 4. functioon() 5. /函数 6. 7. if() 8. /条件 9. 10. for() 11. /循环 12. 13. while() 14. /循环 15. 16. switch() 17. /多条件 18. 19. with() 20. /作用域 21. 22. try 23. /异常处理 24. 段落结构包含的的内容可以是是一条或多条条语句。可以以在段落起始始标记()前前面添加
8、修饰饰词,如域谓谓词(witth、cattch)、逻逻辑谓词(iif、whiile、foor、swiitch等)、函函数谓词(ffunctiion fnn(arg))等。语句是由多个词词构成的完整整逻辑。在JJavaSccript中中,常用分号号(;)来划划分语句,有有时也可以省省略分号,默默认使用换行行符表示完整整的语句。一条语句可以包包含一个或多多个词。例如如,在下面两两条语句中,第第一条语句只只有一个词,这这是一个指令令词,该指令令只能位于循循环体或swwitch结结构体内。第第二条语句包包含3个词,aleert表示函函数名(即变变量),小括括号表示运算算符,而“提示信息”表示字符符串直
9、接量。1. break; 2. alert(提示信息);一条语句也可以以包含一个或或多个段落。例例如,在下面面这条语句中中,直接把一一个函数当做做一个变量进进行调用。1. (functiion(i) 2. aleert(i); 3. )(提示信信息);还可以把函数包包含在一个闭闭包中形成多多个结构嵌套套,这个嵌套套结构体就构构成了一个复复杂的语句,例例如:1. (functiion(i) 2. retturnffunctiion() 3. alerrt(i); 4. ; 5. )(提示信信息)();语句一般至少包包含一个词或或段落,但是是语句也可以以什么都不包包含,仅由一一个分号进行行标识,这
10、样样的句子称为为空语句。空空语句常用做做占位符。例例如,在下面面这个循环体体内就包含了了一个空语句句。 1. for(varri;ii100;ii+) 2. ; 3. 词语是JavaaScrippt句法结构构中的最小语语义单位,包包括指令(或或称语句)、变变量、直接量量(或常量)、运运算符等。在在JavaSScriptt中,词语之之间必须使用用分隔符进行行分隔,否则则JavaSScriptt就会错误解解析。下面的的代码块是一一个简单的求求两个数平均均值的方法。1. vara=34; 2. varb=56; 3. functioonaveer(c,dd) 4. retturn(c+d)/2; 5
11、. 6. alert(aaver(aa,b);其中var、ffunctiion、reeturn是是指令,这些些指令也是JJavaSccript默默认的关键字字;a、b、cc、d、avver、allert为变变量;34、556是数值直直接量;=、(、)、/、+、,是运算算符。建议3:减少全全局变量污染染定义全局变量有有3种方式:在任何函数外面面直接执行vvar语句。1. varf=vallue;直接添加一个属属性到全局对对象上。全局局对象是所有有全局变量的的容器。在WWeb浏览器器中,全局对对象名为wiindow。 1. window.f=vaalue;直接使用未经声声明的变量,以以这种方式定定
12、义的全局变变量被称为隐隐式的全局变变量。 1. f=vaalue;为方便初学者在在使用前无须须声明变量而而有意设计了了隐式的全局局变量,然而而不幸的是忘忘记声明变量量成了一个非非常普遍的现现象。JavvaScriipt的策略略是让那些被被忘记预先声声明的变量成成为全局变量量,这导致在在程序中查找找Bug变得得非常困难。JavaScrript语言言最为糟糕的的就是它对全全局变量的依依赖性。全局局变量就是在在所有作用域域中都可见的的变量。全局局变量在很小小的程序中可可能会带来方方便,但随着着程序越来越越大,它很快快变得难以处处理。因为一一个全局变量量可以被程序序的任何部分分在任意时间间改变,使得得
13、程序的行为为被极大地复复杂化。在程程序中使用全全局变量降低低了程序的可可靠性。全局变量使在同同一个程序中中运行独立的的子程序变得得更难。如果果某些全局变变量的名称与与子程序中的的变量名称相相同,那么它它们将会相互互冲突并可能能导致程序无无法运行,而而且通常还使使程序难以调调试。实际上,这些全全局变量削弱弱了程序的灵灵活性,应该该避免使用全全局变量。努努力减少使用用全局变量的的方法:在应应用程序中创创建唯一一个个全局变量,并并定义该变量量为当前应用用的容器。1. varMy=; 2. My.namee= 3. fiirst-nname:ffirst, 4. laast-naame:laast 5
14、. ; 6. My.workk= 7. nummber:123, 8. onee: 9. namee:one, 10. timee:22012-99-14112:55, 11. cityy:bbeijinng 12. , 13. twoo: 14. namee:ttwo, 15. timee:22012-99-12112:42, 16. cityy:sshanghhai 17. 18. ;只要把多个全局局变量都追加加在一个名称称空间下,将将显著降低与与其他应用程程序产生冲突突的概率,应应用程序也会会变得更容易易阅读,因为为My.woork指向的的是顶层结构构。当然也可可以使用闭包包体将信息隐隐
15、藏,它是另另一种有效减减少“全局污污染”的方法法。在编程语言中,作作用域控制着着变量与参数数的可见性及及生命周期。这这为程序开发发提供了一个个重要的帮助助,因为它减减少了名称冲冲突,并且提提供了自动内内存管理。1. varfooo=funnctionn() 2. varra=1,b=2; 3. varrbar=functtion() 4. varb=3,c=4;/a=1,b=3,c=45. a+=b+c;/a=8,b=3,c=46. ;/a=1,b=2,c=undeffined7. barr();/a=21,b=2,c=undeffined8. ;大多数采用C语语言语法的语语言都拥有块块级作用
16、域。对对于一个代码码块,即包括括在一对大括括号中的语句句,其中定义义的所有变量量在代码块的的外部是不可可见的。定义义在代码块中中的变量在代代码块执行结结束后会被释释放掉。但是是,对于JaavaScrript语言言来说,虽然然该语言支持持代码块的语语法形式,但但是它并不支支持块级作用用域。JavaScrript支持持函数作用域域,定义在函函数中的参数数和变量在函函数外部是不不可见的,并并且在一个函函数中的任何何位置定义的的变量在该函函数中的任何何地方都可见见。其他主流编程语语言都推荐尽尽可能迟地声声明变量,但但是在JavvaScriipt中就不不能够这样,因因为它缺少块块级作用域,最最好的做法是
17、是在函数体的的顶部声明函函数中可能用用到的所有变变量。建议4:注意JJavaSccript数数据类型的特特殊性(1)1.防止浮点数数溢出二进制的浮点数数不能正确地地处理十进制制的小数,因因此0.1+0.2不等等于0.3。1. num=00.1+0.2;/0.300000000000000000044这是JavaSScriptt中最经常报报告的Bugg,并且这是是遵循二进制制浮点数算术术标准(IEEEE 7554)而导致致的结果。这这个标准适合合很多应用,但但它违背了数数字基本常识识。幸运的是是,浮点数中中的整数运算算是精确的,所所以小数表现现出来的问题题可以通过指指定精度来避避免。例如,针针对
18、上面的相相加可以这样样进行处理:1. a=(1+2)/100;/0.3这种处理经常在在货币计算中中用到,在计计算货币时当当然期望得到到精确的结果果。例如,元元可以通过乘乘以100而而全部转成分分,然后就可可以准确地将将每项相加,求求和后的结果果可以除以1100转换回回元。2.慎用JavvaScriipt类型自自动转换在JavaSccript中中能够自动转转换变量的数数据类型,这这种转换是一一种隐性行为为。在自动转转换数据类型型时,JavvaScriipt一般遵遵循:如果某某个类型的值值被用于需要要其他类型的的值的环境中中,JavaaScrippt就自动将将这个值转换换成所需要的的类型,具体体说
19、明见表11.1。表1.1数据据类型自动转转换(续)如果把非空对象象用在逻辑运运算环境中,则则对象被转换换为truee。此时的对对象包括所有有类型的对象象,即使是值值为falsse的包装对对象也被转换换为truee。如果把对象用在在数值运算环环境中,则对对象会被自动动转换为数字字,如果转换换失败,则返返回值为NaaN。当数组被用在数数值运算环境境中时,数组组将根据包含含的元素来决决定转换的值值。如果数组组为空数组,则则被转换为数数值0。如果果数组仅包含含一个数字元元素,则被转转换为该数字字的数值。如如果数组包含含多个元素,或或者仅包含一一个非数字元元素,则返回回NaN。当对象用于字符符串环境中时
20、时,JavaaScrippt能够调用用toStrring()方法把对象象转换为字符符串再进行相相关计算。当当对象与数值值进行加号运运算时,则会会尝试将对象象转换为数值值,然后参与与求和运算。如如果不能够将将对象转换为为有效数值,则则执行字符串串连接操作。建议4:注意JJavaSccript数数据类型的特特殊性(2)3.正确检测数数据类型使用typeoof运算符返返回一个用于于识别其运算算数类型的字字符串。对于于任何变量来来说,使用ttypeoff运算符总是是以字符串的的形式返回以以下6种类型型之一:numberrstringgbooleaanobjecttfunctiionundefiined
21、不幸的是,在使使用typeeof检测nnull值时时,返回的是是“objeect”,而而不是“nuull”。更更好的检测nnull的方方式其实很简简单。下面定定义一个检测测值类型的一一般方法:1. functioontyppe(o) 2. retturn(o=null)?nnull:(tyypeofo); 3. 这样就可以避开开因为nulll值影响基基本数据的类类型检测。注注意:typpeof不能能够检测复杂杂的数据类型型,以及各种种特殊用途的的对象,如正正则表达式对对象、日期对对象、数学对对象等。对于对象或数组组,可以使用用consttructoor属性,该该属性值引用用的是原来构构造该对象
22、的的函数。如果果结合typpeof运算算符和connstrucctor属性性,基本能够够完成数据类类型的检测。表表1.2所示示列举了不同同类型数据的的检测结果。表1.2数据据类型检测使用consttructoor属性可以以判断绝大部部分数据的类类型。但是,对对于undeefinedd和null特殊殊值,就不能能使用connstrucctor属性性,因为使用用JavaSScriptt解释器会抛抛出异常。此此时可以先把把值转换为布布尔值,如果果为truee,则说明不不是undeefinedd和null值,然然后再调用cconstrructorr属性,例如如:1. varvallue=undeffi
23、ned; 2. alert(ttypeoffvaluue);/unndefinned 3. alert(vvalue&vaalue.cconstrructorr);/undeefinedd 4. varvallue=null; 5. alert(ttypeoffvaluue);/obbject 6. alert(vvalue&vaalue.cconstrructorr);/nulll对于数值直接量量,也不能使使用consstructtor属性,需需要加上一个个小括号,这这是因为小括括号运算符能能够把数值转转换为对象,例例如:1. alert(10).cconstrructorr);使用toSt
24、rring()方法检测对对象类型是最最安全、最准准确的。调用用toStrring()方法把对象象转换为字符符串,然后通通过检测字符符串中是否包包含数组所特特有的标志字字符可以确定定对象的类型型。toSttring()方法返回回的字符串形形式如下: 1. objecttclasss建议4:注意JJavaSccript数数据类型的特特殊性(3)其中,objeect表示对对象的通用类类型,claass表示对对象的内部类类型,内部类类型的名称与与该对象的构构造函数名对对应。例如,AArray对对象的claass为“AArray”,FFunctiion对象的的classs为“Funnctionn”,Da
25、tte对象的cclass为为“Datee”,内部MMath对象象的classs为“Maath”,所所有Erroor对象(包包括各种Errror子类类的实例)的的classs为“Errror”。客户端JavaaScrippt的对象和和由JavaaScrippt实现定义义的其他所有有对象都具有有预定义的特特定classs值,如“WWindoww”、“Doocumennt”和“FForm”等等。用户自定定义对象的cclass值值为“Objject”。class值提提供的信息与与对象的coonstruuctor属属性值相似,但但是classs值是以字字符串的形式式提供这些信信息的,而不不是以构造函函数
26、的形式提提供这些信息息的,所以在在特定的环境境中是非常有有用的。如果果使用typpeof运算算符来检测,则则所有对象的的classs值都为“OObjectt”或“Fuunctioon”,所以以此时的cllass值不不能够提供有有效信息。但是,要获取对对象的claass值的唯唯一方法是必必须调用Obbject对对象定义的默默认toSttring()方法,因因为不同对象象都会预定义义自己的tooStrinng()方法法,所以不能能直接调用对对象的toSStringg()方法。例例如,下面对对象的toSStringg()方法返返回的就是当当前UTC时时间字符串,而而不是字符串串“objject DD
27、ate”。1. vard=newDaate(); 2. alert(dd.toSttring();/当当前UTC时间字字符串要调用Objeect对象定定义的默认ttoStriing()方方法,可以先先调用Objject.pprotottype.ttoStriing对象的的默认toSStringg()函数,再再调用该函数数的applly()方法法在想要检测测的对象上执执行。结合上上面的对象dd,具体实现现代码如下: 1. vard=newDaate(); 2. varm=Objeect.prrototyype.tooStrinng; 3. alert(mm.applly(d);/obbjectD
28、ate下面是一个比较较完整的数据据类型安全检检测方法。1. /安全检测测JavaSScriptt基本数据类类型和内置对对象 2. /参数:oo表示检测的的值 3. /*返回值:返回字符串串undeefinedd、numbber、boollean、striing、funcction、regeexp、arraay、datee、erroor、objeect或nulll*/ 4. functioontyppeOf(oo) 5. varr_toSStringg=Objject.pprotottype.ttoStriing; 6. /获取对象的的toStrring()方法引用 7. /列举基本数数据类型和
29、内内置对象类型型,可以进一一步补充该数数组的检测数数据类型范围围 8. varr_typpe= 9. unddefineed:undeefinedd, 10. nummber:nuumber, 11. booolean:bbooleaan, 12. strring:sttring, 13. obbjectFuncttion:ffunctiion, 14. obbjectRegExxp:reggexp, 15. obbjectArrayy:arraay, 16. obbjectDate:date, 17. obbjectErrorr:erroor 18. 19. retturn_typetype
30、oofo|_ttype_toStrring.ccall(oo)|(o?objject:nuull); 20. 应用示例:1. vara=Mathh.abs; 2. alert(ttypeOff(a);/functtion上述方法适用于于JavaSScriptt基本数据类类型和内置对对象,而对于于自定义对象象是无效的。这这是因为自定定义对象被转转换为字符串串后,返回的的值是没有规规律的,并且且不同浏览器器的返回值也也是不同的。因因此,要检测测非内置对象象,只能够使使用consstructtor属性和和instaaceof运运算符来实现现。建议4:注意JJavaSccript数数据类型的特特殊性(
31、4)4.避免误用pparseIIntparseInnt是一个将将字符串转换换为整数的函函数,与paarseFlloat(将将字符串转换换为浮点数)对对应,这两种种函数是JaavaScrript提供供的两种静态态函数,用于于把非数字的的原始值转换换为数字。 在开始转换时,pparseIInt会先查查看位置0处处的字符,如如果该位置不不是有效数字字,则将返回回NaN,不不再深入分析析。如果位置置0处的字符符是数字,则则将查看位置置1处的字符符,并重复前前面的测试,依依此类推,直直到发现非数数字字符为止止,此时paarseInnt()函数数将把前面分分析合法的数数字字符转换换为数值并返返回。1. p
32、arseInnt(1223abc);/123 2. parseInnt(1.73);/1 3. parseInnt(.1123);/NaN浮点数中的点号号对于parrseIntt来说属于非非法字符,因因此它不会被被转换并返回回,这样,在在使用parrseIntt时,就存在在潜在的误用用风险。例如如,我们并不不希望parrseIntt(16)与parrseIntt(16 tons)产生相同同的结果。如如果该函数能能够提醒我们们出现额外文文本就好了,但但它不会那么么做。对于以0为开头头的数字字符符串,parrseIntt()函数会会把它作为八八进制数字处处理,先把它它转换为数值值,然后再转转换为十
33、进制制的数字返回回。对于以00x开头的数数字字符串, parseeInt()函数则会把把它作为十六六进制数字处处理,先把它它转换为数值值,然后再转转换为十进制制的数字返回回。例如:1. vard=0100;/八进制 2. vare=0x110;/十六进制制 3. parseInnt(d);/8 4. parseInnt(e);/16如果字符串的第第一个字符是是0,那么该该字符串将基基于八进制而而不是十进制制来求值。在在八进制中,88和9不是数数字,所以pparseIInt(008)和pparseIInt(009)的结结果为0,这这个错误导致致了在程序解解析日期和时时间时经常会会出现问题。幸幸运
34、的是,pparseIInt可以接接受一个基数数作为参数,这这样parsseInt(08,10)结果果为8,paarseInnt(099,10)结果为9。因因此,建议读读者在使用pparseIInt时,一一定要提供这这个基数参数数。通过在parsseInt中中提供基数参参数,可以把把二进制、八八进制、十六六进制等不同同进制的数字字字符串转换换为整数。例例如,下面把把十六进制数数字字符串123abbc转换为为十进制整数数。1. parseInnt(1223abc,16);/11946684再如,把二进制制、八进制和和十进制数字字字符串转换换为整数:1. parseInnt(100,2);/把把二进
35、制数字字10转换为十十进制整数为为2 2. parseInnt(100,8);/把把八进制数字字10转换为十十进制整数为为8 3. parseInnt(100,100);/把把十进制数字字10转换为十十进制整数为为10建议5:防止JJavaSccript自自动插入分号号JavaScrript语言言有一个机制制:在解析时时,能够在一一句话后面自自动插入一个个分号,用来来修改语句末末尾遗漏的分分号分隔符。然然而,由于这这个自动插入入的分号与JJavaSccript语语言的另一个个机制发生了了冲突,即所所有空格符都都被忽略,因因此程序可以以利用空格格格式化代码。这两种机制的冲冲突,很容易易掩盖更为严
36、严重的解析错错误。有时会会不合时宜地地插入分号。例例如,在reeturn语语句中自动插插入分号将会会导致这样的的后果:如果果returrn语句要返返回一个值,这这个值的表达达式的开始部部分必须和rreturnn在同一行上上,例如:1. varf=funcction() 2. retturn 3. 4. stattus:ttrue 5. ; 6. 看起来这里要返返回一个包含含statuus成员元素素的对象。不不幸的是,JJavaSccript自自动插入分号号让它返回了了undeffined,从从而导致下面面真正要返回回的对象被忽忽略。当自动插入分号号导致程序被被误解时,并并不会有任何何警告提醒。
37、如如果把放在在上一行的尾尾部而不是下下一行的头部部,就可以避避免该问题,例例如:1. varf=funcction() 2. retturn 3. stattus:ttrue 4. ; 5. 为了避免省略分分号引起的错错误,建议养养成好的习惯惯,不管一行行内语句是否否完整,只要要是完整的语语句都必须增增加分号以表表示句子结束束。为了方便阅读,当当长句子需要要分行显示时时,在分行时时应确保一行行内不能形成成完整的逻辑辑语义。例如如,下面代码码是一条连续续赋值的语句句,通过分行行显示可以更更清楚地查看看它们的关系系。这种分行行显示,由于于一行内不能能形成独立的的逻辑语义,因因此JavaaScrip
38、pt不会把每每一行视为独独立的句子,从从而不会产生生歧义。1. vara= 2. b= 3. c=4;以上语句在一行行内显示如下下: 1. vara=b=c=4;对于下面这条语语句,如果不不能正确分行行显示,就很很容易产生歧歧义。该句子子的含义:定定义一个变量量i,然后为为其赋值,如如果变量a为为true,则则赋值为1,否否则就判断变变量b,如果果b为truue,则赋值值为2,否则则就判断变量量c,如果cc为truee,则赋值为为3,否则赋赋值为4。 1. vari=a?1:b?2:c?33:4;下面的分行显示示就是错误的的,因为表达达式a ? 1: b能能够形成独立立的逻辑语义义,所以Jaa
39、vaScrript会自自动在其后添添加分号来表表示一个独立立的句子。1. vari=a?1:b 2. ?2:c 3. ?3:4;安全的方法应该该采用如下的的分行显示,这这样每一行都都不能形成独独立的语义。 1. vari=a?1 2. :b?22 3. :c?33 4. :4;总之,在编写代代码时,应养养成使用分号号结束句子的的良好习惯,凡凡是完整的句句子就应该使使用分号进行行分隔。分行行显示的句子子应该确保单单行不容易形形成独立的合合法的逻辑语语义。建议6:正确处处理JavaaScrippt特殊值(11)1.正确使用NNaN和InnfinittyNaN是IEEEE 7544中定义的一一个特殊
40、的数数量值。它不不表示一个数数字,尽管下下面的表达式式返回的是ttrue。1. typeofNaN=nuumber/trrue该值可能会在试试图将非数字字形式的字符符串转换为数数字时产生,例例如:1. +0/00 2. +oopss/NaaN如果NaN是数数学运算中的的一个运算数数,那么它与与其他运算数数的运算结果果就会是NaaN。如果有有一个表达式式产生出NaaN的结果,那那么至少其中中一个运算数数是NaN,或者者在某个地方方产生了NaaN。可以对NaN进进行检测,但但是typeeof不能辨辨别数字和NNaN的区别别,并且NaaN不等同于于它自己,所所以,下面的的代码结果令令人惊讶。1. N
41、aN=NaN/fallse 2. NaN!=NaN/truue为了方便检测NNaN值,JJavaSccript提提供isNaaN静态函数数,以辨别数数字与NaNN区别。 1. isNaN(NNaN)/trrue 2. isNaN(00)/fallse 3. isNaN(oops)/truue 4. isNaN(0)/faalse判断一个值是否否可用做数字字的最佳方法法是使用issFinitte函数,因因为它会筛除除掉NaN和和Infinnity。IInfiniity表示无无穷大。当数数值超过浮点点数所能够表表示的范围时时,就要用IInfiniity表示。反反之,负无穷穷大为Innfinitty
42、。使用isFinnite函数数能够检测NNaN、正负负无穷大。如如果是有限数数值,或者可可以转换为有有限数值,那那么将返回ttrue。如如果只是NaaN、正负无无穷大的数值值,则返回ffalse。不幸的是,issFinitte会试图把把它的运算数数转换为一个个数字。因此此,如果值不不是一个数字字,使用issFinitte函数就不不是一个有效效的检测方法法,这时不妨妨自定义issNumbeer函数。1. varisNNumberr=funnctionnisNuumber(valuee) 2. retturnttypeoffvaluue=nummber&issFinitte(vallue); 3. 2.正确使用nnull和uundefiinedJavaScrript有5种基本类型型:Striing、Numbeer、Booleean、Null和Undeffined。前前3种都比较好好理解,后面面两种就稍微微复杂一点。Null 类型只有一个值,就是null;Undefined类型也只有一个值,即undefined。 null 和unde