JS高级程序编程读书笔记:一.基本概念

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  

会单独拿出来研究

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值