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
会单独拿出来研究