【讀書筆記】-- 你不知道的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

小結:以上是《中》的第一部分筆記。

相關文章
相關標籤/搜索