《你不知道的JavaScript》是一個不錯的JavaScript系列書,書名可能有些標題黨的意思,但實符其名,很多地方會讓你有耳目一新的感覺。

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

ES6中JavaScript的類型有:null、undefined、string、number、boolean、object和symbol。但為啥上面的表達式為true呢?這其實是JavaScript的一個bug。最初設(shè)計是根據(jù)類型對應(yīng)的前三位是不是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,雖然這有點迷惑,但用以檢測一個變量會比較安全:

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn) 

直接操作一個未申明的變量會報錯,所以下面這樣檢測比較好:

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

等同于:

if(window.a){}

通過window的全局屬性去檢測,看起來更簡潔,但是要注意場景,前提是存在window,且a為全局變量。

3.數(shù)字的語法

1)JavaScript中數(shù)字前面的0可以省略,小數(shù)后面的0也可以省略

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

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

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

實際上可能不會有人這么寫,直接對一個數(shù)字進行小數(shù)處理。但讓我們認識到,對于數(shù)字而言,‘.’被視為常量12的一部分,所以上面的錯誤就相當于沒有屬性訪問運算符'.'來調(diào)用toFixed方法。

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

以上三種是可以的,以區(qū)分'.'是屬性訪問器還是常量的一部分。

2)最小數(shù)

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

這個錯誤大家應(yīng)該都知道,JavaScript中的浮點數(shù)并不是十分精確。所以0.1+0.2的結(jié)果并非剛好等于0.3。再比如我的ofo賬單中

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

所以在JavaScript中判斷浮點數(shù)需要帶上一個精度范圍。

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

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

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

numbersCloseEnoughToEqual(0.1+0.2,0.3) //true

3)最大數(shù)

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

我們對一個字符串進行轉(zhuǎn)換,parseFloat和parseInt都只能到16位。其他的后面全部補0了。這個要注意了,讓前端傳給的id啊,唯一號啊都應(yīng)該是字符串的,當然這在調(diào)用api的時候沒有問題,因為都是字符串。但有一次我遇到這個坑是因為ProtoBuf的自定義協(xié)議中別人定義了個19位的int。結(jié)果就拿不到數(shù)據(jù)了。

4.void 運算符

 void不改變表達式的結(jié)果,只讓表達式不返回值。我們可以使用void 0來獲得undefined。void 1、void true和undefined之間并沒有實質(zhì)的區(qū)別。

 photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

其實每個表達式都有返回值,我們在console中操作的時候就會發(fā)現(xiàn)。第三個undefined是void的作用。 像賦值表達式,定義表達式的返回值無法運用。

 photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

特殊一點的比如setTimeout這個方法,每次調(diào)用都會返回一個數(shù)字,這個數(shù)字其實是計數(shù)器的一個唯一標識符,用來讓你取消的。你可以用 void抹掉,但這簡直是給自己挖坑。

5.不是數(shù)字的數(shù)字

NaN是個很奇葩的對象,自己不等于自己。

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

typeof NaN==='number'//true

但它確實屬于number。

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

雖然window自帶isNaN方法,但這個方法有bug。居然判斷字符也返回true。但可以用到它的奇葩特性來判斷NaN。它是唯一一個自己不等于自己的值。

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

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

Number.isNaN(b)

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

6.奇特的~運算符

位操作符(|和~)和某些特殊數(shù)字一起使用時會產(chǎn)生類似強類型轉(zhuǎn)換的效果,返回另外一個數(shù)字。

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

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

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

 超過11位成了有符號的整數(shù)。用乘法相當于parsInt,16位是正確的。超過了就說不好了。

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

~ 非操作符,在JavaScript中的效果就是值的負數(shù)減一。

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

這個特性可以配合indexOf一起使用:

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

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//  沒有找到匹配!}

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

上面兩種比起下面的4種要簡潔一些。當然你可能一開始不習(xí)慣,這到底是匹配了還是沒匹配。記住-1取反為0,0為false。

7.假值的相等比較

==會進行隱式的強制類型轉(zhuǎn)換

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

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

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

這個結(jié)果真讓人大跌眼鏡。{}和[]其實是為真的。

 photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

photoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動軟件開發(fā)培訓(xùn),網(wǎng)站設(shè)計培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)

更夸張的是:

所以 false==[] 很讓人迷惑,背后是因為都轉(zhuǎn)成了0==0。所以最好是使用===來避免不經(jīng)意的強制類型轉(zhuǎn)換。

8.運算符優(yōu)先級

&&與||是比較熟悉的。a&&b,如果a為真,則返回b。a||b,如果a為真返回a,否則返回b。

&&可以用來代替單個if。

a&&foo();

如果a為真就執(zhí)行foo(),如果要執(zhí)行多個語句,可以用括號括起來,中間用逗號分開。||可以用來處理默認值。

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

&& 運算符的優(yōu)先級高于 || ,而 || 的優(yōu)先級又高于 ? : 。

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

相當于:

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

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

你的關(guān)注和支持是我寫作的最大動力~ 
書山有路群:452450927
出處:http://www.cnblogs.com/stoneniqiu/
github:https://github.com/stoneniqiu 
簡書:http://www.jianshu.com/u/14144fcb167d 
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面

http://www.cnblogs.com/stoneniqiu/p/6603406.html