• 【读书笔记】-- 你不知道的JavaScript


    《你不知道的JavaScript》是一个不错的JavaScript系列书,书名可能有些标题党的意思,但实符其名,很多地方会让你有耳目一新的感觉。

    1.typeof null === "object"// true

    ES6中JavaScript的类型有:null、undefined、string、number、boolean、object和symbol。但为啥上面的表达式为true呢?这其实是JavaScript的一个bug。最初设计是根据类型对应的前三位是不是0来判断是否为一个object。而null全部为0,所以null的类型误判为object。要准确判断null需要这样:

    var a = null;
    (!a && typeof a === "object"); // true

    因为null本身是一个假值("",undefined,false,0)。而像function,{},Array等都属于object。

    2.undefined与未申明

    而对于未赋值的变量,type of 返回undefined,未申明的变量也返回undefined,虽然这有点迷惑,但用以检测一个变量会比较安全:

     

    直接操作一个未申明的变量会报错,所以下面这样检测比较好:

    if(typeof a !=="undefined"){}

    等同于:

    if(window.a){}

    通过window的全局属性去检测,看起来更简洁,但是要注意场景,前提是存在window,且a为全局变量。

    3.数字的语法

    1)JavaScript中数字前面的0可以省略,小数后面的0也可以省略

    且toFixed方法本身带有四舍五入的效果。 

    实际上可能不会有人这么写,直接对一个数字进行小数处理。但让我们认识到,对于数字而言,‘.’被视为常量12的一部分,所以上面的错误就相当于没有属性访问运算符'.'来调用toFixed方法。

    以上三种是可以的,以区分'.'是属性访问器还是常量的一部分。

    2)最小数

    这个错误大家应该都知道,JavaScript中的浮点数并不是十分精确。所以0.1+0.2的结果并非刚好等于0.3。再比如我的ofo账单中

    所以在JavaScript中判断浮点数需要带上一个精度范围。

    if (!Number.EPSILON) {
    Number.EPSILON = Math.pow(2,-52);
    };
    function numbersCloseEnoughToEqual(n1,n2) {
    return Math.abs( n1 - n2 ) < Number.EPSILON;
    }
    numbersCloseEnoughToEqual(0.1+0.2,0.3) //true

    3)最大数

    我们对一个字符串进行转换,parseFloat和parseInt都只能到16位。其他的后面全部补0了。这个要注意了,让前端传给的id啊,唯一号啊都应该是字符串的,当然这在调用api的时候没有问题,因为都是字符串。但有一次我遇到这个坑是因为ProtoBuf的自定义协议中别人定义了个19位的int。结果就拿不到数据了。

    4.void 运算符

     void不改变表达式的结果,只让表达式不返回值。我们可以使用void 0来获得undefined。void 1、void true和undefined之间并没有实质的区别。

     

    其实每个表达式都有返回值,我们在console中操作的时候就会发现。第三个undefined是void的作用。 像赋值表达式,定义表达式的返回值无法运用。

     

    特殊一点的比如setTimeout这个方法,每次调用都会返回一个数字,这个数字其实是计数器的一个唯一标识符,用来让你取消的。你可以用 void抹掉,但这简直是给自己挖坑。

    5.不是数字的数字

    NaN是个很奇葩的对象,自己不等于自己。

    typeof NaN==='number'//true

    但它确实属于number。

    虽然window自带isNaN方法,但这个方法有bug。居然判断字符也返回true。但可以用到它的奇葩特性来判断NaN。它是唯一一个自己不等于自己的值。

    if (!Number.isNaN) {
    Number.isNaN = function(n) {
    return n !== n;
    };
    }
    
    Number.isNaN(b)

    6.奇特的~运算符

    位操作符(|和~)和某些特殊数字一起使用时会产生类似强类型转换的效果,返回另外一个数字。

    0|undefined//0
    0|NaN//0
    0|Infinity //0

    你可能想到了用来代替parseInt。but,只有10位。

     超过11位成了有符号的整数。用乘法相当于parsInt,16位是正确的。超过了就说不好了。

    ~ 非操作符,在JavaScript中的效果就是值的负数减一。

    这个特性可以配合indexOf一起使用:

    var a = "Hello World";
    if (~a.indexOf( "lo" )) { // true
    //  找到匹配!
    }
    if (!~a.indexOf( "ol" )) { // true
    //  没有找到匹配!
    }
    if (a.indexOf( "lo" ) >= 0) { // true
    //  找到匹配!
    }
    if (a.indexOf( "lo" ) != -1) { // true
    //  找到匹配!
    }
    if (a.indexOf( "ol" ) < 0) { // true
    //  没有找到匹配!
    }
    if (a.indexOf( "ol" ) == -1) { // true
    //  没有找到匹配!
    }

    上面两种比起下面的4种要简洁一些。当然你可能一开始不习惯,这到底是匹配了还是没匹配。记住-1取反为0,0为false。

    7.假值的相等比较

    ==会进行隐式的强制类型转换

    "0" == null; // false
    "0" == undefined; // false
    "0" == false; // true --  晕!
    "0" == NaN; // false
    "0" == 0; // true
    "0" == ""; // false
    false == null; // false
    false == undefined; // false
    false == NaN; // false
    false == 0; // true --  晕!
    false == ""; // true --  晕!
    false == []; // true --  晕!
    false == {}; // false
    "" == null; // false
    "" == undefined; // false
    "" == NaN; // false
    "" == 0; // true --  晕!
    "" == []; // true --  晕!
    "" == {}; // false
    0 == null; // false
    0 == undefined; // false
    0 == NaN; // false
    0 == []; // true --  晕!
    0 == {}; // false

    这个结果真让人大跌眼镜。{}和[]其实是为真的。

     

    更夸张的是:

    所以 false==[] 很让人迷惑,背后是因为都转成了0==0。所以最好是使用===来避免不经意的强制类型转换。

    8.运算符优先级

    &&与||是比较熟悉的。a&&b,如果a为真,则返回b。a||b,如果a为真返回a,否则返回b。

    &&可以用来代替单个if。

    a&&foo();

    如果a为真就执行foo(),如果要执行多个语句,可以用括号括起来,中间用逗号分开。||可以用来处理默认值。

    function foo(a){
     a=a||1;
     //....
    }

    && 运算符的优先级高于 || ,而 || 的优先级又高于 ? : 。

    a && b || c ? c || b ? a : c && b : a

    相当于:

    (a && b || c) ? (c || b) ? a : (c && b) : a

    小结:以上是《中》的第一部分笔记。

  • 相关阅读:
    Prism_Commanding(2)
    Prism_简介(1)
    思维导图
    自学_DOM<五>
    spring cloud 微服务之 -- 配置文件拆分之道
    idea 2019破解方法(真实可用,完美破解)
    小白的springboot之路(十四)、AOP
    小白的springboot之路(十三)、过滤器、监听器、拦截器
    闲话计算机端口
    小白的springboot之路(十二)、集成log4j2日志
  • 原文地址:https://www.cnblogs.com/stoneniqiu/p/6603406.html
Copyright © 2020-2023  润新知