(本文为阮一峰js标准教程的学习笔记,旨在总结该教程中涉及的知识点大纲及个人所做的一些拓展,方便作为“目录”或者“大纲”复习和查漏补缺,详细内容请参见阮一峰教程原文)
第二部分 语法
**********第三章 数值***************一.概述1.所有数都是以64位浮点数形式储存的。1与1.0相同(8bit、也就是64位二进制数)2、JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。3、由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。0.1 + 0.2 === 0.3// false0.3 / 0.1// 2.9999999999999996(0.3 - 0.2) === (0.2 - 0.1)// false4、容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算,参见《运算符》一节的”位运算“部分。二、数值精度1、国标IEEE754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。 第1位:符号位,0表示正数,1表示负数 第2位到第12位:指数部分 第13位到第64位:小数部分(即有效数字)IEEE 754 规定,有效数字第一位默认总是1,不保存在64位浮点数之中。因此,JavaScript 提供的有效数字最长为53个二进制位。2.精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即-(2的53次方-1)到2的53次方-1,都可以精确表示。【内部细节不详】Math.pow(2, 53)// 9007199254740992Math.pow(2, 53) + 1// 9007199254740992Math.pow(2, 53) + 2// 9007199254740994Math.pow(2, 53) + 3// 9007199254740996Math.pow(2, 53) + 4// 9007199254740996Math.pow(2, 53)// 9007199254740992// 多出的三个有效数字,将无法保存9007199254740992111// 9007199254740992000三.数值范围1.64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。分出一半表示负数,则 JavaScript 能够表示的数值范围为21024到2-1023(开区间),超出这个范围的数无法表示。2.指数部分等于或超过最大正值1024,JavaScript 会返回Infinity “正向溢出”;3.指数等于或超过最小负值-1023(即非常接近0),JavaScript 会直接把这个数转为0,“负向溢出”。var x = 0.5;for(var i = 0; i < 25; i++) { x = x * x;}x // 04.js能表示的最大值和最小值,JavaScript 提供Number对象的MAX_VALUE和MIN_VALUE属性表示。Number.MAX_VALUE // 1.7976931348623157e+308Number.MIN_VALUE // 5e-324四、数值的表示法1、使用字面量表示 比如: 0xFF(十六进制)2、科学计数法,允许字符e或E后跟一个整数,表示*10的多少次方。3、js自动将数值转科学技术法的几种情况(其他均用字面量形式表示)(1)小数点前的数字多于21位。1234567890123456789012// 1.2345678901234568e+21123456789012345678901// 123456789012345680000(2)小数点后的零多于5个。// 小数点后紧跟5个以上的零,// 就自动转为科学计数法0.0000003 // 3e-7// 否则,就保持原来的字面形式0.000003 // 0.000003五、数值的进制1.使用字面量时,js对整数提供四种进制。十进制 没有前导0十六 前导0x或0X八 0o 或者0O二 0b 或者0B2. 特殊:单独的前导0--前导0表示八进制,处理时很容易造成混乱。ES5的严格模式和ES6,已经废除了这种表示法,但是浏览器目前还支持。通常来说,有前导0的数值会被视为八进制,但是如果前导0后面有数字8和9,则该数值被视为十进制。0888 // 888 十进制0777 // 511 被认为是八进制3.默认js将十六、八、二自动转十(js依赖先导辨认)4.前导标明进制,又出现不属于该进制数字报错。六、特殊数值1、正零和负零1.1js内部有两个0,+0和-0是等价的/1.2严格相等+0===-0 +0 -0 01.3js中任何一个数都有负值,0不例外;【不讨论NaN】1.4唯一区别场合:+0和-0当作分母,返回值不相等;(1/+0)===(1/-0) //false;原因:一个得到+Infinity 另一个-Infinity2.NaN2.1含义:表示非数字2.2主要出现场景:将字符串转为数字;2.3一些函数运算结果出现NaNMath.acos(2) // NaNMath.log(-1) // NaNMath.sqrt(-1) // NaN2.40 / 0 // NaN2.5,NaN不是一种独立的数据类型,而是一种特殊数值,它的数据类型依然属于Number,使用typeof运算符可以看得很清楚。typeof NaN // 'number'2.6运算规则:*不等于任何值,包括自身NaN === NaN // false*由于数组的indexOf方法,内部使用的是严格相等运算符,所以该方法对NaN不成立。[NaN].indexOf(NaN) // -1*Boolean(NaN) // 转布尔false*与任何数包括自己运算都是NaN*2.7 判断NaN方法2.7.1 isNaN方法:遇到NaN或者可以被转成NaN的值返回true; *只对数有效,传入其他值自动转。 *传入字符串也会为true; *isNaN返回true可能是NaN,也可能是别的比如字符串.isNaN('Hello') // true// 相当于isNaN(Number('Hello')) // true出于同样的原因,对于对象和数组,isNaN也返回true。isNaN({}) // true// 等同于isNaN(Number({})) // trueisNaN(['xzy']) // true// 等同于isNaN(Number(['xzy'])) // true但是,对于空数组和只有一个数值成2.72员的数组,isNaN返回false。isNaN([]) // falseisNaN([123]) // falseisNaN(['123']) // false2.7.2使用isNaN之前,最好判断一下数据类型。function myIsNaN(value) { return typeof value === 'number' && isNaN(value);}2.7.3判断NaN更可靠的方法是,利用NaN是JavaScript之中唯一不等于自身的值这个特点,进行判断。function myIsNaN(value) { return value !== value;}3.Infinity3.1定义:特殊数值 number类型,不独立成数据类型;3.2表示无穷3.3场景:*正的太大*负的太小*非0数值除以0,得Infinity注意:0/0是NaN3.4正负之分:+Infinity表示正无穷 -Infinity表示负无穷3.5Infinity大于一切数,-Infinity小于一切 不考虑NaN3.6Infinity与NaN比较,怎么比都返回false;3.71/-0 -Infinity-1/-0 Infinity-1/0 -Infinity1/0 Infinity3.8正负向溢出,被零除,js都不报错,说明单纯数学运算几乎没有可能抛出错误;3.9Infinity的四则运算符合无穷的运算规则;【这条不严谨,并非完全符合】3.10 0*Infinity//NaN 【居然不是0! 】3.11 null与Infinity计算 null转0 等同于与0计算3.12 undefined与Infinity计算全部返回NaN3.13Infinity加上或乘以Infinity,返回的还是Infinity。Infinity + Infinity // InfinityInfinity * Infinity // InfinityInfinity减去或除以Infinity,得到NaN。Infinity - Infinity // NaNInfinity / Infinity // NaN3.14isFinite函数isFinite函数返回一个boolean检查是不是一个正常的数值,或者能否转化为正常数值,遇到NaN,Infinity返回false;isFinite(Infinity) // falseisFinite(-1) // trueisFinite(true) // trueisFinite(NaN) // false七、与数值相关的全局方法1.parseInt()1.1 字符串转整数1.2 转出来的数会有向下取整的效果:原因是认不出小数点。1.3要求参数是字符串。1.4相关问题:1.4.1 字符串头部带空格无影响;【中间、尾部空格未知】1.4.2 遇到不能转为数字的字符,返回已经转好的;1.4.3 参数不是字符串,先转字符再转数字,这会导致一些令人意外的结果。parseInt(0x11, 36) // 43// 等同于parseInt(String(0x11), 36)parseInt('17', 36)1.4.4 字符串的第一个字符不能转化为数字的情况,返回NaN,但是不包括"-123"这样后面跟着数的正负号1.4.5 parseInt返回值两种可能: 十进制数 NaN1.4.6 对于那些会自动转化科学技术的情况,parseInt会将科学技术的表示方法视为字符串,最终导致奇怪结果出现。parseInt(0.0000008) //等同于parseInt('8e-')//81.4.7 涉及进制转换*parseInt('0x10')字符串是带前导的数,parseInt会按照相应的进制解析(命中字符串前导后,会用十六进制解读字符串,为十六进制数,然后转成十进制数返回)*parseInt('1000',10)第二参默认是十,以十进制解析字符串,除非命中字符串先导或者手动修改这个第二参*第二个参数是0、undefined和null,则直接忽略。parseInt('10', 37) // NaNparseInt('10', 1) // NaNparseInt('10', 0) // 10parseInt('10', null) // 10parseInt('10', undefined) // 10*第二参是整数,这个整数只有在2到36之间,才能得到有意义的结果,超出这个范围,则返回NaN。*第二参不是数,或者是小数会自动转成整数,该作死用法此处不研究*指定了解析进制,字符串中出现无意义字符,从最高位返回可转数,最高位如果都转不了,返回NaN*指定第二参,就按照第二参的进制解析字符串;未指定第二参,字符串中有先导被命中,按照先导的进制解析;以上两个都没有,默认十进制解析;parseInt('011',2) 会以二进制处理字符串"011" //得到结果是十进制3parseInt('011') 不同浏览器不一样,有的能认出先导0,有的认不出来认为是10进制;*对于八进制的前缀0,加上第一参非字符串转字符串,两个问题在一起就更纠结了parseInt(011, 2) // NaN// 等同于parseInt(String(011), 2)由于String(011)这一步转为"9",具体过程是识别出其中的先导,以八进制解析数字为十进制数字9,完了转为字符串。*ES5不再允许将带有前缀0的数字视为八进制数,而是要求忽略这个0。但是,为了保证兼容性,大部分浏览器并没有部署这一条规定。【parseFloat认不出前导
parseInt parseFloat前后空格过滤,中间空格算识别不出的字符parseFloat不认前导,没有第二参数来做进制转换功能parseInt有设定参数控制解析进制的功能,toString()有指定参数控制输出进制的功能;
】2.parseFloat方法()2.1含义:parseFloat方法用于将一个字符串转为浮点数;2.2遇到不能转为浮点数的字符,则返回已转好的;2.3自动过滤前导空格,参数字符串首位空格忽略2.4字符串第一个字符都不能转直接返回NaN2.5参数不是字符串,先转字符串(自动),再转浮点数2.6字符串书写符合科学计数法,能被命中(能认得出来),返回的数值会做相应转换。parseFloat('314e-2') //3.142.7 parseFloat解析过程中遇到首位(+、-),数字0-9,小数点,科学计数法中的指数标记(e或者E)以外字符,就认不出来了2.8parseFloat()方法对比Number函数。parseFloat(true) // NaNNumber(true) // 1parseFloat(null) // NaNNumber(null) // 0parseFloat('') // NaNNumber('') // 0parseFloat('123.45#') // 123.45Number('123.45#') // NaN