比较 JavaScript 日期对象也能踩坑?涨姿势了
直觉上,两个相同的日期之间比较应该是相等的,然而结果并不是这样:
const d1 = new Date('2019-06-01');
const d2 = new Date('2018-06-01');
const d3 = new Date('2019-06-01');
d1 === d3; // false
d1 == d3; // false
可以看到,无论用===还是==,结果都是false。细想也不奇怪,毕竟是两个独立的 JS 对象,并不是基本数据类型的变量。那该怎么判断日期是否相等呢?
可以用toString()或者valueOf()。日期对象的toString()方法将日期转成 ISO 日期字符串形式,而valueOf() 方法则将日期转成毫秒数字形式的时间戳。
const d1 = new Date('2019-06-01');
const d2 = new Date('2018-06-01');
const d3 = new Date('2019-06-01');
// Sat Jun 01 2019 08:00:00 GMT+0800 (中国标准时间)
d1.toString();
d1.valueOf(); // 1559347200000
d1.toString() === d2.toString(); // false
d1.toString() === d3.toString(); // true
d1.valueOf() === d2.valueOf(); // false
d1.valueOf() === d3.valueOf(); // true
有意思的是,虽然== 和 === 不能用来比较日期对象,< 和> 却可以:
d1 < d2; // false
d1 < d3; // false
d2 < d1; // true
因此,要判断日期a是否在日期 b之前,只要判断a < b是否为true。另外,日期之间还能用-操作符相减,返回毫秒差值。
const d1 = new Date('2019-06-01');
const d2 = new Date('2018-06-01');
const d3 = new Date('2019-06-01');
d1 - d3; // 0
d1 - d2; // 1 年的毫秒数, 1000 * 60 * 60 * 24 * 365
也就是说,你可以用a - b 结果的正负来判断两个日期的先后。
数组排序的坑日期对象数组排序的结果很可能出乎意料。比如下面这个排序:
const d1 = new Date('2017-06-01');
const d2 = new Date('2018-06-01');
const d3 = new Date('2019-06-01');
[d2, d1, d3].sort(); // [d2, d3, d1]
按理说从小到大排序应该是[d1, d2, d3],结果很意外。这是为什么呢?原来,JavaScript 数组的sort方法默认是比较元素的字符串形式。因此,上面的sort实际上是基于下面的结果来排序的:
[ 'Fri Jun 01 2018 08:00:00 GMT+0800 (中国标准时间)',
'Sat Jun 01 2019 08:00:00 GMT+0800 (中国标准时间)',
'Thu Jun 01 2017 08:00:00 GMT+0800 (中国标准时间)' ]
怎么解决这个问题?很简单,传一个自定义的排序函数compare()给sort()方法。这个compare()函数的返回值确定了两个元素的大小(先后顺序):
0 表示 a 和b 相等
正值表示 a > b,也就是a在b后面
负值表示 a < b,也就是a在b前面
由于 JavaScript 日期对象可以直接相减,那这个比较函数就很简单了:
const d1 = new Date('2017-06-01');
const d2 = new Date('2018-06-01');
const d3 = new Date('2019-06-01');
[d2, d1, d3].sort((a, b) => a - b); // [d1, d2, d3]
下次碰到数组数组默认排序出现这样的结果你也就不感到奇怪了:
const a = [1, 4, 3, 12];
a.sort(); // [1, 12, 3, 4]
所以为了防止出现 Bug,应该传入自定义排序函数。
新上课程
课程:《PythonDjango4开发入门到实战》
课程介绍:django是python应用广泛的web框架,可以快速搭建从小到大的网站,本课程从零带你学会django框架,完成多个实战网站功能的开发。讲师:裴帅帅讲师介绍:前百度资深大数据工程师,现某一线互联网推荐系统架构师,8年大数据、机器学习研发经验,常年使用和实战Python/Java双语言。课程优惠:原价 299 元,目前上线限时5 折优惠,普通用户只需要 149.5 即可获得该门课程永久权限。
相关文章
-
1、console.log输出console.log(([][[]]+[])[+!![]]+([]+{})[!+[]+!![]]) 2、优雅的取随机字符串Math.random().toString(16).substring(2) 3、if比较["toString"]()==="10" 4、优雅的取整vara=2.3
-
在电影《叶问》中,甄子丹饰演的叶问每天会利用木人桩练习武艺,使得泳春拳法成为肌肉记忆的一部分。临场迎敌时,身体会使用正确的拳式,自然而然。 我以为JS编程基本功的练习于武术拳法的练习是一样的。通过一套有效的『拳法』将JS基本功内置其中,反复练习,使得JS技艺成为手指记忆的一部分。这样,当面对实际开发时,我们就不需要为
-
前言我们知道Javascript语言的执行环境是"单线程"。也就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。 这种模式虽然实现起来比较简单,执行环境相对单纯,但是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因
-
一、是什么函数式编程是一种"编程范式"(programmingparadigm),一种编写程序的方法论 主要的编程范式有三种:命令式编程,声明式编程和函数式编程 相比命令式编程,函数式编程更加强调程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而非设计一个复杂的执行过程
-
探索函数式编程,通过它让你的程序更具有可读性和易于调试--MattBanz 本文导航?什么不是函数式编程04%?纯函数08%?不变性17%?函数组合42%?递归50%?高阶函数69%?柯里化80%?总结95%编译自|https://opensource.com/article/17/6/functional-java
-
作者丨AlexanderHafemann 译者|布加迪 用JavaScript编写第一段代码可能需要一天左右的时间,但深入了解其未知知识和背景知识可能让你在整个职业生涯受益无穷! 作用域(scope) 简而言之,作用域就是"你可以在代码中访问声明的地方"。 我们有两种作用域:全局作用域和局部作用域,区别在于你可以在代
-
前面的文章我们一起玩了Flowable中的ServiceTask,今天我们再来看看Flowable中的脚本任务。 1.脚本任务个人感觉脚本任务和我们前面说的ServiceTask很像,都是流程走到这个节点的时候自动做一些事情,不同的是,在ServiceTask中,流程在这个节点中所做的事情是用Java代码写的,在脚本任
-
网络研究院 新的Windows零日漏洞允许威胁参与者使用恶意的独立JavaScript文件绕过Web标记安全警告。已经看到威胁参与者在勒索软件攻击中使用零日漏洞。Windows包含一个称为Web标记(MoTW)的安全功能,该功能将文件标记为已从Internet下载,因此应谨慎处理,因为它可能是恶意的。MoTW标志作为
-
写在前面 为了提升应用稳定性,我们对前端项目开展了脚本异常治理的工作,对生产上报的jserror进行了整体排查,试图通过降低脚本异常的发生频次来提升相关告警的准确率,结合最近在这方面阅读的相关资料,尝试阶段性的做个总结,下面我们来介绍下js异常处理的一些经验。先说概念 什么是异常先来看一下官方的定义:Errorobj
-
喜讯 在2022年9月,由海南省计算机学会组织的全省全国青少年信息学奥林匹克联赛(NOIP)及CSP-JS非专业级别的能力认证考试,以及2022海南省青少年信息学竞赛中,我校共六名学生参加第一轮认证暨2022海南省青少年信息学竞赛(初赛),并全部入围第二轮认证暨复赛,其中获得二等奖2人,三等奖3人。 向以上获奖的同学表