js懵圈之強等(===)弱等(==)衍生出的類型轉化、NaN、getElement*和querySelector*的問題

/*===可有可無的開頭start===*/
做爲一個年輕的前端從業者,近期趾高氣昂的去各類面試,抱着找虐心態去單挑的結果就是被各類面試題晃斷腳踝並被yan射,而後開始質問本身對js的掌握爲什麼如此淺薄,爲什麼當初很差好學世界上最好的語言php。
固然,這不只提醒了我得背背面試題,還要時刻謹記,要寫安全規範的javascript代碼
而後小總結了一下那天面試上來的就被隔扣的第一題。
/*===可有可無的開頭end===*/javascript

問題

null === undefined; // false
null == undefined; // true
null === 0; // false
null == 0; // false
false === 0; // false
false == 0; // true
true === 1; // false
true == 1; // true
true == '1'; // true
true == 2; // false
undefined === 0; // false
undefined == 0; // false

NaN === NaN; // false
NaN == NaN; // false
!NaN == !NaN; // false
!NaN; // true
null == NaN; // false
!null == !NaN; // true
!null === !NaN; // true
if(!NaN) console.log('媽呀,這都是啥啊'); // '媽呀,這都是啥啊'

false || 0; // 0
!(false || 0) // true
true && 1; // 1
true && 2; // 2
!(true && 2) // false
!(false || 2) // false

let a = 123;
let b = new Number(123);
a === b; // false
a == b; // true

let a = document.getElementsByTagName('a');
let b = document.getElementsByTagName('a');
a === b; //true

let c = document.querySelectorAll('a');
let d = document.querySelectorAll('a');
c === d; //false

/*待續。。。*/

解答

答案在問題裏邊,真是皮得很...php

其實這些是我根據當時的面試題整理和擴充的,有些代碼中真的是碰不上,可是順手都寫上了。其實有些經驗的開發者都會知道這些,小的不才在這再說那麼一小下。html

還有一些ES6中的set和map和symbol等後期會寫到另外一篇上。前端

正經解答

這道題中涉及到強等、弱等、js中基礎類型轉換、懸疑NaN、null和undefined、選擇器等java

js中的弱類型造福了人類,處處都是它貼心的幫你各類轉換,讓咱們的代碼在瀏覽器上、在webview上、在node裏、在各類模擬器裏、在喜馬拉雅山上、在尼斯湖裏、在握不緊的指尖上、在人生的光輝歲月裏跑的流暢且難以預料。node

因此:如何安全的寫js,其實真的很重要(忘了這是誰說的了)。es6

如下只是個人一些理解,歡迎指正?web

1. === 和 == 和類型轉換

雖然看了一個很棒的總結(https://www.cnblogs.com/nelso...面試

可是本身的想法仍是要講:數組

‘===’:
(1) 若是是基礎類型進行比較,第一件事兒就是比較一下兩邊的數據類型,若是不同,直接false
(2) 若是兩個數據類型(這裏指的仍是基礎類型)同樣,那接下來就是直接的「值」的比較了
(3) 若是是引用類型的變量或者是內置函數構造出的變量進行比較,那麼就是指針的比較了
(4) null和undefined,再強等面前,只和本身相等。

‘==’:
(1) 若是是基礎類型進行比較,類型同樣沒得說,類型不同,第一件事就是轉一下,字符串轉數字再進行值的比較,boolean類型轉爲數字

這裏稍微總結了一下,能夠頑固的認爲 == 都是再比較數字,全部的都轉換爲數字,而後進行「值」的比較了(不知道接下來這麼理解是好仍是壞)

舉個例子:'123' == 123 // true
其實就是 new Number('123') == 123,兩邊值同樣,那就是true,不同就是false;

再舉個例子:
    true == 1; //true    
    true == '1' // true
    true == 2; // false
    false == 0 // true
    false == -1 // false
    
拿true == '1'來講
這樣就是 new Number(true) == new Number('1')
其實仍是兩個爲1的‘值’去比較
(new Number(true)返回一個 Number {1},new Number(false)返回一個 Number {0})

(2)若是是引用類型的變量或者是內置函數構造出的變量 和 基礎數據類型 去比較,那就是這些變量的值拿出來去比較,例如 '123asd' == new String('123ads') 返回true

(3)若是是引用類型的變量或者是內置函數構造出的變量 相互比較,那仍是指針的比較

2. NaN

NaN,感受其實就是一個爲了不非數字的數字操做引發程序報錯而設計的一個表示‘Not a Number’的存在,網上有好多好多介紹它的文字

NaN等於誰

由於討論的強等和弱等,那在這隻說一點:NaN和誰都不等,無論什麼等

因此
———— NaN === NaN 是false
———— NaN==NaN也是false
———— new Number(NaN) == new Number(NaN)也是 false

很難理解爲何是這樣,以爲是一個bug,其實我本身感受這樣是對的,由於它就是‘單純的表示’這不是一個數字,並無說是什麼,such as:

NaN + 1; // NaN  那麼一個數加一仍是本身,那本身原本就不該該等於本身。。。

let a = 12/0 //a是NaN
let b = 13/0 //b是NaN,可是很簡單看出a原本就不該該等於b(雖然再高數上它們是相等的)
let raptors = 81/'Kobe' //raptors也是NaN,raptors原本就不應等於a或者b

因此任何和NaN去比較的話,那都是「不等」!

NaN的判斷

那麼,該如何判斷是否是NaN呢
不賣關子了,我就是來講 isNaN 和 Number.isNaN

你們都知道isNaN======>

isNaN不是看上去那個意思,不是判斷「是一個NaN」,而是判斷「不是一個數字類型的值」,isNaN看上去就是幫你在內部把傳入的值進行了一次 new Number(param)的操做,而後new Number(param)返回NaN那就判斷爲true,可是字符串等類型就沒有辦法判斷,以下:

isNaN(NaN); // 是個true
isNaN(NaN+1); // 固然仍是個true

isNaN(123); //固然false
isNaN('123'); // 幫你轉了個類型,就是內部執行了一下isNaN(new Number('123')),因此仍是false
isNaN('Curry'); //返回true,內部執行了一下(new Number('Curry')返回了NaN

第五行的字符串,居然被斷定爲NaN,實際上它的確不是一個數字,可是它的的確確不是咱們須要判斷的是一個NaN,因此這個方法只是用來判斷「不是一個數字類型的值」

而後你們還知道Number.isNaN======>

es6來補漏了,Number.isNaN的出現解決了你們但願判斷「是一個NaN」的操做。以下

Number.isNaN('Curry'); //返回false

NaN結束了

3. getElement* 和 querySelector*

在問題中有這樣一個東西:

let a = document.getElementsByTagName('a');
let b = document.getElementsByTagName('a');
a === b; // true

let c = document.querySelectorAll('a');
let d = document.querySelectorAll('a');
c === d; //false

這衍生出來的:getElementsByTagName查出來是什麼?querySelectorAll查出來的又是什麼?

MDN上告訴咱們:

———— getElementsByTagName查出來的是HTMLCollection,HTMLCollection是一個動態的dom節點集合,綁定在document的live上,隨着document變化隨時更新,指向每個符合選擇要求的dom節點,這既是爲何上邊例子中 a===b 爲 true 的緣由了

———— querySelectorAll查出來的是NodeList,是一個單純的選擇器選出的dom節點集合,這就是爲何上邊例子中 c===d 爲 false 了

HTMLCollection和NodeList都是隻讀的。jQuery也是使用的querySelectorAll,因此jQuery選擇器選擇出來也是對NodeList進行操做,因此:

var a = $('a');
var b = $('a');
a === b; // false

因此,事件委託真偉大...

總結

其實由NaN、選擇器、===和==、基本數據類型轉換、內置函數構造出的對象結合進數組中,去判斷數組值相等,去去重、去求交併補等操做,並結合set和map,都有不少討論的話題,但願下次能分享給你們

感謝各位的閱讀,這些只是我本身的一些理解和想法,但願不正確的地方各位可以幫忙指正。

相關文章
相關標籤/搜索