ECMAScript区分大小写
标识符:第一个字符: 字母、下划线、$
其他字符: 数字、字母、下划线、$
惯例使用驼峰命名法 nMyNumber
严格模式:处理ECMA3中一些不确定的行为(支持的浏览器:IE10+、FF4+、Safari5.1+、Opera12+、Chrome)
添加: "use strict" ;
在函数上方包含该编译指示,该函数将将在严格模式下执行;在顶部添加,则整个脚本都会使用严格模式
一.数据类型
5种基本类型:Undefined,Null,Bollean,Number,String
1种复杂类型:Object
1.1 Undefined
只有一个值:undefined
如果只声明一个变量而未对其初始化,则该值为undefined;
例子1:声明一个变量而未对其初始化 -> undefined
var uTest ; //仅声明,未初始化赋值 alert( typeof uTest ); //undefined alert( uTest == undefined );//true 此时该值为undefined
例子2:未声明变量 -> 使用typeof 时,会得到undefined
alert(typeof c) ;//undefined alert(c); //程序报错
1.2Null类型
只有一个值:null
特殊值null被认为是一个空的对象引用,所以使用typeof null时,该结果为 object,但在Safari5及之前版本、Chrome7及之前版本其值为 function
undefined派生自null,所以他们的相等性测试返回true
alert(null == undefined); //true
null被用来解除引用
1.3Bollean类型
两个值:true 和 false (该值区分大小写,所以True不是布尔值,而是标识符)
转型函数Boolean()
//数据类型 转换为true 转换为false //String 非空字符串 空字符串"" //Number 非零数值(包括无穷大) 0或NaN //Object 任何对象 null //Undefiend undefined
1.4 Number类型
八进制:第一位为0 ,如果该值大于7,则以十进制解析
八进制:011 = 十进制:9;
八进制:081 = 十进制:81;//有数值8超过7,所以以十进制解析
十六进制:前两位为0x,值A-F可以大写也可以小写,其他同八进制
可以有+0和-0,但其被认为相等。
1.4.1 浮点数
写法: 0.1 .1(忽略小数点前的值,该写法不推荐)
保存浮点数需要的内存是整数的两倍,所以ECMA会尽量将浮点数转换为整数,即如果1.0会被保存为1
默认情况下,会将小数点后面带有6个零以上的浮点数转换为以e表示法表示的数值
浮点数值的最高精度是17位小数,但在算数计算时精度远远不如整数。
浮点精度计算问题:
var a = 0.1; var b = 0.2; if(a+b == 0.3) { alert('true'); } else { alert('wrong:'+ (a+b)); }结果为wrong:0.30000000000000004;
如果a=0.15,b=0.15;结果为true
a=0.25,b=0.05;结果也为true
原因:浮点数值计算采用IEEE754标准的双精度浮点数计算方式
去网上查了一些资料,总结如下(没仔细研究,只是简单的了解一下):
IEEE 754 规定了两种基本浮点格式:单精度和双精度。
IEEE单精度格式具有24 位有效数字精度(包含符号号),并总共占用32 位。
IEEE双精度格式具有53 位有效数字精度(包含符号号),并总共占用64 位。
十进制0.1
=> 二进制0.00011001100110011…(循环0011)
=>尾数为1.1001100110011001100…1100(共52位,除了小数点左边的1),指数为-4(二进制移码为00000000010),符号位为0
=> 计算机存储为:0 00000000100 10011001100110011…11001
=> 因为尾数最多52位,所以实际存储的值为0.00011001100110011001100110011001100110011001100110011001
而十进制0.2
=> 二进制0.0011001100110011…(循环0011)
=>尾数为1.1001100110011001100…1100(共52位,除了小数点左边的1),指数为-3(二进制移码为00000000011),符号位为0
=> 存储为:0 00000000011 10011001100110011…11001
因为尾数最多52位,所以实际存储的值为0.00110011001100110011001100110011001100110011001100110011
那么两者相加得:
0.00011001100110011001100110011001100110011001100110011001
+ 0.00110011001100110011001100110011001100110011001100110011
= 0.01001100110011001100110011001100110011001100110011001100
转换成10进制之后得到:0.30000000000000004
解决办法:
书中给出的建议是:永远不要测试某个特定的浮点数值
经测试:无法使用parseFloat解决,因为本身浮点计算方式有问题
1.使用近似值
var a = 0.1; var b = 0.2; if( a+b - 0.3 < Math.abs(0.000000000000001)) //0.000000000000001为我们需要的精度 { alert('true'); } else { alert('wrong:'+ (a+b)); }
会损失精度
2.将其转化为整数进行计算
var a = 0.1 *10 ; var b = 0.2*10 ; if(a+b == 0.3*10 ) { alert('true'); } else { alert('wrong:'+ (a+b)); }注:这种方法很麻烦
3.使用toFixed方法
4.转换为字符串,拷贝了网上大神的代码
a:
function add(a, b) { var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c = 0; } try { d = b.toString().split(".")[1].length; } catch (f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (mul(a, e) + mul(b, e)) / e; } function sub(a, b) { var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c = 0; } try { d = b.toString().split(".")[1].length; } catch (f) { d = 0; } return e = Math.pow(10, Math.max(c, d)), (mul(a, e) - mul(b, e)) / e; } function mul(a, b) { var c = 0, d = a.toString(), e = b.toString(); try { c += d.split(".")[1].length; } catch (f) {} try { c += e.split(".")[1].length; } catch (f) {} return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c); } function div(a, b) { var c, d, e = 0, f = 0; try { e = a.toString().split(".")[1].length; } catch (g) {} try { f = b.toString().split(".")[1].length; } catch (g) {} return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), mul(c / d, Math.pow(10, f - e)); }
b:
/** ** 加法函数,用来得到精确的加法结果 ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 ** 调用:accAdd(arg1,arg2) ** 返回值:arg1加上arg2的精确结果 **/ function accAdd(arg1, arg2) { var r1, r2, m, c; try { r1 = arg1.toString().split(".")[1].length; } catch (e) { r1 = 0; } try { r2 = arg2.toString().split(".")[1].length; } catch (e) { r2 = 0; } c = Math.abs(r1 - r2); m = Math.pow(10, Math.max(r1, r2)); if (c > 0) { var cm = Math.pow(10, c); if (r1 > r2) { arg1 = Number(arg1.toString().replace(".", "")); arg2 = Number(arg2.toString().replace(".", "")) * cm; } else { arg1 = Number(arg1.toString().replace(".", "")) * cm; arg2 = Number(arg2.toString().replace(".", "")); } } else { arg1 = Number(arg1.toString().replace(".", "")); arg2 = Number(arg2.toString().replace(".", "")); } return (arg1 + arg2) / m; } //给Number类型增加一个add方法,调用起来更加方便。 Number.prototype.add = function (arg) { return accAdd(arg, this); };
/** ** 减法函数,用来得到精确的减法结果 ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。 ** 调用:accSub(arg1,arg2) ** 返回值:arg1加上arg2的精确结果 **/ function accSub(arg1, arg2) { var r1, r2, m, n; try { r1 = arg1.toString().split(".")[1].length; } catch (e) { r1 = 0; } try { r2 = arg2.toString().split(".")[1].length; } catch (e) { r2 = 0; } m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度 n = (r1 >= r2) ? r1 : r2; return ((arg1 * m - arg2 * m) / m).toFixed(n); } // 给Number类型增加一个mul方法,调用起来更加方便。 Number.prototype.sub = function (arg) { return accMul(arg, this); };
/** ** 乘法函数,用来得到精确的乘法结果 ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 ** 调用:accMul(arg1,arg2) ** 返回值:arg1乘以 arg2的精确结果 **/ function accMul(arg1, arg2) { var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); try { m += s1.split(".")[1].length; } catch (e) { } try { m += s2.split(".")[1].length; } catch (e) { } return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); } // 给Number类型增加一个mul方法,调用起来更加方便。 Number.prototype.mul = function (arg) { return accMul(arg, this); };
/** ** 除法函数,用来得到精确的除法结果 ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。 ** 调用:accDiv(arg1,arg2) ** 返回值:arg1除以arg2的精确结果 **/ function accDiv(arg1, arg2) { var t1 = 0, t2 = 0, r1, r2; try { t1 = arg1.toString().split(".")[1].length; } catch (e) { } try { t2 = arg2.toString().split(".")[1].length; } catch (e) { } with (Math) { r1 = Number(arg1.toString().replace(".", "")); r2 = Number(arg2.toString().replace(".", "")); return (r1 / r2) * pow(10, t2 - t1); } } //给Number类型增加一个div方法,调用起来更加方便。 Number.prototype.div = function (arg) { return accDiv(this, arg); };
1.4.2 数值范围
能够表示的最大数值:Number.MAX_VALUE最小数值为:Number.MIN_VALUE
大多数浏览器中数值为:1.7976931348623157e+308 5e-324
如果在计算过程中超过了这个值,将会转换为特殊的Infinity值(-Infinity:负无穷大,Infinity:正无穷大),该值无法进行下一次计算。即:
如果x为Infinity,对其进行的计算值都为Infinity;如果x1为Infinity,x2为Infinity,x1-x2值为NaN,x1 == x2值为true;
想要确定一个数值是不是有穷的(即在最大最小值之间),使用函数isFinite(),如果在最大最小值之间则返回true,否则false
Number.NEGATIVE_INFINITY (-Infinity) Number.POSITIVE_INFINITY (Infinity)
哦,不要使用Number.MAX_VALUE+1来产生Infinity(该结果仍然为Number.MAX_VALUE,即Number.MAX_VALUE+1 ==Number.MAX_VALUE结果
为true,所以我将开始的表示二字标红),因为Number.MAX_VALUE使用科学计数法(e表示法)计数,该数字已经失真,如果实在想用,就使用Number.MAX_VALUE+1*Math.pow(10,292)吧,但Number.MAX_VALUE+1*Math.pow(10,291)仍然会失真。
1.4.3 NaN
not a number,是一个特殊的数值,任何数/非数值会产生NaN。注:0/0会产生NaN,正数/0是Infinity,负数/0是-Infinity
任何涉及NaN的计算都会返回NaN,NaN与任何值都不相等,包括自己。
检测是否为NaN的函数:isNaN() 如果是数值则返回true,否则返回false
1.4.4 数值转换
Number(),parseInt(),parseFloat()函数
1.5 String类型
转义字符 \\ 斜杠、\' 单引号、\" 双引号
字符串转换方法:toString() 可以传入一个参数,进制的基数2(以二进制输出)、8、10、16,null和undefined没有这个方法
字符串转换函数:String() 可以把任意类型值转换为字符串,包括null和undefined
1.6 Object
会单独拿出来研究