改善JavaScript程序的188个建议-读书笔记

建议一:防止浮点数溢出
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;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,791评论 6 545
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,795评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,943评论 0 384
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 64,057评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,773评论 6 414
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,106评论 1 330
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,082评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,282评论 0 291
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,793评论 1 338
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,507评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,741评论 1 375
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,220评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,929评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,325评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,661评论 1 296
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,482评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,702评论 2 380