IE10中基于date属性的对象数组sort排序功能失效问题
问题原因
- 核心原因是IE10的
Array.prototype.sort采用不稳定的快速排序实现:Chrome等现代浏览器的sort逻辑为稳定排序,当两个元素的排序字段相等时会保留原始相对位置;IE10在比较函数返回0时会随机调整相等元素的位置,如果你的对象数组中存在多个date属性相等的元素,就会出现看起来排序完全失效的情况。示例2的简单日期数组排序看起来正常,是因为相等的日期字符串完全一致,你无法感知它们的相对顺序变化。 - 次要兼容风险:IE10不支持ES6的
let关键字,如果你未使用转译工具将代码转为ES5语法,代码会直接抛出语法错误,可优先排查该问题。 - 隐藏兼容坑:
Date.parse对MM/DD/YYYY格式的解析在部分IE10小版本中存在偶发异常,即使示例2运行正常,也不排除在对象属性访问场景下出现解析错误的可能。
修复方案
修改排序逻辑,手动解析日期保证兼容性,同时增加第二排序规则抵消IE10排序不稳定的问题:
// 先标记原始索引,作为相等值的排序依据,保证排序结果和现代浏览器一致 objectsArr.forEach(function(item, index) { item._tmpIndex = index; }); objectsArr = objectsArr.sort(function (a, b) { // 手动拆分日期字符串解析,不依赖Date.parse的兼容实现 function getTime(dateStr) { var datePart = dateStr.split('/'); // 注意月份从0开始计数 return new Date(+datePart[2], +datePart[0] - 1, +datePart[1]).getTime(); } var diff = getTime(a.date) - getTime(b.date); // 日期不相等时按时间戳排序,相等时按原始索引排序 return diff !== 0 ? diff : a._tmpIndex - b._tmpIndex; }); // 清理临时添加的索引属性 objectsArr.forEach(function(item) { delete item._tmpIndex; });
内容的提问来源于stack exchange,提问作者Adam Mor
相关产品推荐
相关产品推荐

