zoukankan      html  css  js  c++  java
  • [bug] JS sort 函数在 ios 中无效

    首先,请原谅我做一次标题党;

    但我觉得从发现问题到最后解决问题的过程还是蛮有意思的,特此记录一下;

    背景

    近两天开发的航班延误宝是内嵌在客户端(android、ios)webview 中的 H5 页面。其中有部分内容需要前端排序后再显示。代码很简单:

        let m = [6,4,8,10,3,5]
        console.log('排序前:', [6,4,8,10,3,5])
        m.sort((a, b) => a < b)
        console.log('排序后:', m)
    

    ps:发现这段代码的问题了么?如果你知道原因,为了节省您宝贵的时间,后面内容就不要看啦;

    在 PC 浏览器中打印的内容如下:

    排序前: (6) [6, 4, 8, 10, 3, 5]
    排序后: (6) [10, 8, 6, 5, 4, 3]
    

    但我用 iPhone 进行测试(只测了IOS微信浏览器、IOS航班管家客户端),却有不一样的体验:

    WTF!结果和没排序一样,为甚?

    解决

    最开始推测可能是 sort 存在兼容问题。于是,用插入排序替代sort进行测试,结果正常。

    后来,在张(zhen)老(da)师(tui)的指导下,了解了sort的实现规范,才明白,原来是上面的实现有问题

    哪里有问题?

    sort实现的规范中有这么一条:**若 comparefn (a,b) === 0,则有 a === b 且 b === a **。

    此时我们再看var comparefn = (a, b) => a < b,它等同于var comparefn = (a, b) => a < b ? 1 : 0

    它有一个隐藏的漏洞:当a >= b时,comparefn(a,b) === 0。而根据规范,通过comparefn(a,b) === 0可以推测出a === b,显然这里互相矛盾。

    所以,我写的这个comparefn原本就是错误的,holyshit!

    那么正确的写法应该是:var comparefn = (a, b) => b - a

    完结撒花;

    再问:为什么android和ios对此表现的不一样呢?应该是两家在具体实现上有所不同。

    更多:

    array.prototype.sort 实现规范

  • 相关阅读:
    期末总结
    作业01 第一次作业 入门
    C语言I博客作业09
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言|博客作业05
    通过Excel批量导入数据-Java代码
    python3-easygui模块安装
    com.alibaba.fastjson.JSONArray cannot be cast to XX
  • 原文地址:https://www.cnblogs.com/fayin/p/9023342.html
Copyright © 2011-2022 走看看