• [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 实现规范

  • 相关阅读:
    关于asp.net中Repeater控件的一些应用
    Linux查看程序端口占用情况
    php 验证身份证有效性,根据国家标准GB 11643-1999 15位和18位通用
    给Nginx配置一个自签名的SSL证书
    让你提升命令行效率的 Bash 快捷键 [完整版]
    关系数据库常用SQL语句语法大全
    php 跨域 form提交 2种方法
    Vimium~让您的Chrome起飞
    vim tab设置为4个空格
    CENTOS 搭建SVN服务器(附自动部署到远程WEB)
  • 原文地址:https://www.cnblogs.com/fayin/p/9023342.html
Copyright © 2020-2023  润新知