Javascript 如何实现Array.prototype.sort默认比较函数? 背景

Javascript 如何实现Array.prototype.sort默认比较函数? 背景,javascript,sorting,Javascript,Sorting,我需要实现一个与Array.prototype.sort的默认比较函数具有相同行为的函数 阅读文档后,我偶然发现: 默认排序顺序根据字符串Unicode代码点 这是什么意思?这是否意味着我将每个对象都转换为字符串 如果是这样,假设我有数组[2,“a”,{hello:“world”}]这些步骤正确吗 将[2,“a”,{hello:“world”}]转换为[“2”,“a”,{hello:“world”}] 将每个字符串的第一个字符转换为数字 按那个号码订购 问题: 如何实现给定任何对象的比较函数,

我需要实现一个与Array.prototype.sort的默认比较函数具有相同行为的函数

阅读文档后,我偶然发现:

默认排序顺序根据字符串Unicode代码点

这是什么意思?这是否意味着我将每个对象都转换为字符串

如果是这样,假设我有数组
[2,“a”,{hello:“world”}]
这些步骤正确吗

  • [2,“a”,{hello:“world”}]
    转换为
    [“2”,“a”,{hello:“world”}]
  • 将每个字符串的第一个字符转换为数字
  • 按那个号码订购
  • 问题: 如何实现给定任何对象的比较函数,其行为与排序中的比较函数完全相同

    笔记 阅读ECMA规范:

    我现在认为,如果
    comparefn
    undefined
    ,那么他们会使用此算法作为默认值:


    有人能确认吗?

    看起来像是
    解决方案
    在阅读了ECMA规范并四处询问之后,我找到了一个
    defaultCompare
    函数,它模拟了chrome中
    Array.prototype.sort()的默认行为

    const defaultCompare = ( x, y ) => {
        //INFO: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
        //ECMA specification: http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare
    
        if( x === undefined && y === undefined )
            return 0;
    
        if( x === undefined )
            return 1;
    
        if( y === undefined )
            return -1;
    
        const xString = toString(x);
        const yString = toString(y);
    
        if( xString < yString )
            return -1;
    
        if( xString > yString )
            return 1;
    
        return 0;
    };
    
    const toString = obj => {
        //ECMA specification: http://www.ecma-international.org/ecma-262/6.0/#sec-tostring
    
        if( obj === null )
            return "null";
    
        if( typeof obj === "boolean" ||  typeof obj === "number" )
            return (obj).toString();
    
        if( typeof obj === "string" )
            return obj;
    
        if( typeof obj === "symbol" )
            throw new TypeError();
    
        //we know we have an object. perhaps return JSON.stringify?
        return (obj).toString();
    };
    
    module.exports = defaultCompare;
    

    如果在同一个浏览器中测试,输出应该相等。

    a不是ASCII和Unicode中表示的数字。.我已更新了我的问题,以便更清楚,请重新查看!检查规范中的算法:是数组排序的webkit实现。我不知道这是否有帮助,但看起来排序可能会根据内容采取几种不同的路径。我认为您的第二个代码块中有一个拼写错误,有一个句点看起来应该是逗号。另外,由于
    Array.prototype.sort
    对数组进行了适当的排序,因此当您使用
    defaultCompare
    对数组进行排序时,它已经被排序了一次。您应该制作一份数组副本,与第二个比较函数一起使用,以确保预排序不会影响项目的顺序。@philraj很好!我刚刚提交了一个带有那个点的编辑,还将卷曲的引号替换成了直引号。无论如何,这似乎是一个很好的默认比较函数。
    const arr = [ undefined, null, 3, 2, 'B', 'a', 'b', 'A',
    { hello: "world"}, { goodnight: 'moon'} ]
    
    assertEql( arr.sort(), arr.sort(defaultCompare) ); //true