【读书笔记】-- 你不知道的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须要这样:api

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

由于null自己是一个假值("",undefined,false,0)。而像function,{},Array等都属于object。安全

2.undefined与未申明

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

 

直接操做一个未申明的变量会报错,因此下面这样检测比较好:设计

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

等同于:3d

if(window.a){}

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

3.数字的语法

1)JavaScript中数字前面的0能够省略,小数后面的0也能够省略对象

且toFixed方法自己带有四舍五入的效果。 blog

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

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

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 一、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

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

相关文章
相关标签/搜索