摘要:无关紧要的开头作为一个年轻的前端从业者,近期趾高气昂的去各种面试,抱着找虐心态去单挑的结果就是被各种面试题晃断脚踝并被射,然后开始质问自己对的掌握为何如此浅薄,为何当初不好好学世界上最好的语言。
/*===无关紧要的开头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. NaNNaN,感觉其实就是一个为了避免非数字的数字操作引起程序报错而设计的一个表示‘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
摘要:前言新增了两种基本的原生数据集合和加上和现在共有四种,以及由两者衍生出的弱引用集合和。其本身是生成实例数据集合的构造函数,可以接受一个数组或具有接口的数据结构作为参数用来初始化。返回键值对的遍历器对象,键值对为键名键值。 前言 ES6新增了两种基本的原生数据集合:Set和Map(加上Array和Object现在共有四种),以及由两者衍生出的弱引用集合:WeakSet和WeakMap。从...
摘要:引用数据类型引用数据类型值指保存在堆内存中的对象。访问方式是按引用访问。数据类型检测操作符是检测基本类型的最佳工具。未定义布尔值字符串数值对象或函数用于检测引用类型,可以检测到它是什么类型的实例。 前端学习:教程&开发模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试-前端资源汇总 欢迎提issues斧正:数据类型 回味,无穷! 数据类型定义 数据类型分类 基本数据...
摘要:作为一个菜鸡的我而言,在之前讲到过那么多的链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了指向上边,结果就是这个指向指的我万脸懵逼标题换字了,担心被河蟹在经过漫长的通俗易懂的规范阅读之后,分享一下我所认知的指向简而言之, 作为一个js菜鸡的我而言,在之前讲到过那么多的js链式查找机制,比如说原型链,作用域链等等,想当然的把这个机制带入到了this指向上边,结果就是这...
摘要:中的强制转换规则面试官中强制类型转换是一个非常易出现的点,知道强制转换时候的规则吗注规则最好配合下面什么时候发生转换使用这些规则看效果更佳。调用方法用来把对象转换成原始类型的值数值字符串和布尔值。 前言 showImg(https://segmentfault.com/img/bVbu4Fb?w=940&h=400);之前面试了几个开发者,他们确实做过不少项目,能力也是不错的,但是发现...
阅读 2834·2023-04-25 17:59
阅读 674·2023-04-25 15:05
阅读 668·2021-11-25 09:43
阅读 3025·2021-10-12 10:13
阅读 3531·2021-09-27 13:59
阅读 3575·2021-09-23 11:21
阅读 3871·2021-09-08 09:35
阅读 560·2019-08-29 17:12