按月份排序对象数组:Chrome正常Firefox失效的问题排查
解决Firefox中日期格式解析导致的数组排序失败问题
看起来你踩了浏览器兼容性的小坑——Chrome的V8引擎能兼容解析"Jan 2019"这类非标准日期格式,但Firefox的解析规则更严格,不认这种格式,直接返回了Invalid Date,导致排序逻辑彻底失效。
问题根源
不同浏览器对非标准日期字符串的解析支持不一致:Chrome可以识别"月份缩写 年份"的格式,但Firefox只遵循更规范的日期格式(比如"2019-01"或"Jan 01 2019"),所以你用new Date(a.month)在Firefox里拿到的是无效日期,减法运算自然无法提供正确的排序依据。
解决方案:手动解析月份与年份
我们可以绕开浏览器的日期解析差异,自己提取month字段里的关键信息,转换成可比较的数值来排序。具体步骤如下:
- 先做一个月份缩写到数字的映射表,把Jan-Dec对应到0-11(和Date对象的月份索引保持一致);
- 在排序回调里拆分每个
month字符串,提取月份缩写和年份; - 先比较年份,年份相同再比较月份,返回对应的排序差值。
修改后的代码示例
var xAxis = [ {count: 0, month: "Jan 2019"}, {count: 7, month: "Dec 2019"}, {count: 0, month: "Feb 2019"}, {count: 0, month: "Jul 2019"} ]; // 月份缩写与数字的映射表 const monthMap = { "Jan": 0, "Feb": 1, "Mar": 2, "Apr": 3, "May": 4, "Jun": 5, "Jul": 6, "Aug": 7, "Sep": 8, "Oct": 9, "Nov": 10, "Dec": 11 }; xAxis.sort(function(a, b) { // 拆分a的month字段,提取月份缩写和年份 const [aMonthStr, aYear] = a.month.split(' '); const aMonthNum = monthMap[aMonthStr]; // 拆分b的month字段,提取月份缩写和年份 const [bMonthStr, bYear] = b.month.split(' '); const bMonthNum = monthMap[bMonthStr]; // 优先比较年份,年份不同直接返回差值 if (aYear !== bYear) { return parseInt(aYear) - parseInt(bYear); } // 年份相同则比较月份 return aMonthNum - bMonthNum; }); console.log(xAxis); // 预期输出: // [ // {count: 0, month: "Jan 2019"}, // {count: 0, month: "Feb 2019"}, // {count: 0, month: "Jul 2019"}, // {count: 7, month: "Dec 2019"} // ]
方案优势
手动解析完全不依赖浏览器的日期解析规则,无论在Chrome、Firefox还是其他浏览器中都能得到一致的排序结果,而且逻辑清晰易维护——如果之后month字段格式有调整,只需要修改拆分和映射的逻辑即可。
内容的提问来源于stack exchange,提问作者Mojo
相关产品推荐
相关产品推荐

