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,都有不少讨论的话题,但愿下次能分享给你们

感谢各位的阅读,这些只是我本身的一些理解和想法,但愿不正确的地方各位可以帮忙指正。

相关文章
相关标签/搜索