资讯专栏INFORMATION COLUMN

js懵圈之强等(===)弱等(==)衍生出的类型转化、NaN、getElement*和querySe

afishhhhh / 1527人阅读

摘要:无关紧要的开头作为一个年轻的前端从业者,近期趾高气昂的去各种面试,抱着找虐心态去单挑的结果就是被各种面试题晃断脚踝并被射,然后开始质问自己对的掌握为何如此浅薄,为何当初不好好学世界上最好的语言。

/*===无关紧要的开头start===*/
作为一个年轻的前端从业者,近期趾高气昂的去各种面试,抱着找虐心态去单挑的结果就是被各种面试题晃断脚踝并被yan射,然后开始质问自己对js的掌握为何如此浅薄,为何当初不好好学世界上最好的语言php。
当然,这不仅提醒了我得背背面试题,还要时刻谨记,要写安全规范的javascript代码
然后小总结了一下那天面试上来的就被隔扣的第一题。
/*===无关紧要的开头end===*/

问题
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

/*待续。。。*/
解答

答案在问题里边,真是皮得很...

其实这些是我根据当时的面试题整理和扩充的,有些代码中真的是碰不上,但是顺手都写上了。其实有些经验的开发者都会知道这些,小的不才在这再说那么一小下。

还有一些ES6中的set和map和symbol等后期会写到另一篇上。

正经解答

这道题中涉及到强等、弱等、js中基础类型转换、悬疑NaN、null和undefined、选择器等

js中的弱类型造福了人类,到处都是它贴心的帮你各种转换,让我们的代码在浏览器上、在webview上、在node里、在各种模拟器里、在喜马拉雅山上、在尼斯湖里、在握不紧的指尖上、在人生的光辉岁月里跑的流畅且难以预料。

所以:如何安全的写js,其实真的很重要(忘了这是谁说的了)。

以下只是我的一些理解,欢迎指正?

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,都有很多讨论的话题,希望下次能分享给大家

感谢各位的阅读,这些只是我自己的一些理解和想法,希望不正确的地方各位能够帮忙指正。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94465.html

相关文章

  • Set & Map:新生的数据集合及其弱引用衍生

    摘要:前言新增了两种基本的原生数据集合和加上和现在共有四种,以及由两者衍生出的弱引用集合和。其本身是生成实例数据集合的构造函数,可以接受一个数组或具有接口的数据结构作为参数用来初始化。返回键值对的遍历器对象,键值对为键名键值。 前言 ES6新增了两种基本的原生数据集合:Set和Map(加上Array和Object现在共有四种),以及由两者衍生出的弱引用集合:WeakSet和WeakMap。从...

    AprilJ 评论0 收藏0
  • 数组去重的方法

    摘要:因为使用单独的接口存取数据所以不用担心与内置属性重名修改上面的方法后得到除了以外还有这种数据类型这是一个集合它不允许重复元素出现。 NaN NaN属于number,也是一种基本数据类型,只要有一边是 NaN,那么结果就是false 原始值和包装对象 包装对象即基本数据类型经过包装之后得到的对象,作为基本类型值的字符串拥有trim等方法,及length属性,正是由于JS代码会对原始值做一...

    sevi_stuo 评论0 收藏0
  • 温故js系列(1)-基本数据类型引用数据类型判断&存储访问&类型转换

    摘要:引用数据类型引用数据类型值指保存在堆内存中的对象。访问方式是按引用访问。数据类型检测操作符是检测基本类型的最佳工具。未定义布尔值字符串数值对象或函数用于检测引用类型,可以检测到它是什么类型的实例。 前端学习:教程&开发模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试-前端资源汇总 欢迎提issues斧正:数据类型 回味,无穷! 数据类型定义 数据类型分类 基本数据...

    jone5679 评论0 收藏0
  • js深入(四)万脸懵圈的this指向

    摘要:作为一个菜鸡的我而言,在之前讲到过那么多的链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了指向上边,结果就是这个指向指的我万脸懵逼标题换字了,担心被河蟹在经过漫长的通俗易懂的规范阅读之后,分享一下我所认知的指向简而言之, 作为一个js菜鸡的我而言,在之前讲到过那么多的js链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了this指向上边,结果就是这...

    pcChao 评论0 收藏0
  • 经常被面试官问到的JavaScript数据类型知识你真的懂吗?

    摘要:中的强制转换规则面试官中强制类型转换是一个非常易出现的点,知道强制转换时候的规则吗注规则最好配合下面什么时候发生转换使用这些规则看效果更佳。调用方法用来把对象转换成原始类型的值数值字符串和布尔值。 前言 showImg(https://segmentfault.com/img/bVbu4Fb?w=940&h=400);之前面试了几个开发者,他们确实做过不少项目,能力也是不错的,但是发现...

    codergarden 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<