使用 Fitzpatrick 量表解码 JavaScript 表情符号排序

当我们考虑在 JavaScript 中对数组进行排序时,我们通常会想象字符串、数字甚至对象按升序或降序排列。但是当数组的元素是表情符号时会发生什么?答案可能会让您感到惊讶,尤其是当肤色修饰符发挥作用时!

在这篇博客中,我们将深入研究 JavaScript 如何处理表情符号排序,探索影响这种行为的**Fitzpatrick 量表**,并展示一些奇怪的示例。

示例

让我们从屏幕截图中的代码片段开始:

["👩🏿", "👩🏾", "👩🏽", "👩🏼", "👩🏻"].sort();

执行时,此代码会产生以下输出:

["👩🏻", "👩🏼", "👩🏽", "👩🏾", "👩🏿"]

乍一看,您可能会想,表情符号是按“从亮到暗”的顺序排列的。要了解为什么会发生这种情况,我们需要深入了解 JavaScript 和 Unicode。

到底发生了什么事?

1. 表情符号的工作原理

每个表情符号都由一个唯一的 **Unicode 代码点** 表示。例如:

  • 👩 由 U+1F469 表示。
  • 🏿(肤色修饰符)由 U+1F3FF 表示。
  • 当显示“👩🏿”这样的表情符号时,它实际上是两个 Unicode 字符的组合:

  • 基本表情符号 (👩)。
  • 肤色调节剂(🏿)。
  • 2. JavaScript 中的排序

    JavaScript 中的 `.sort()` 方法通过比较数组元素的 Unicode 值来工作,默认情况下将它们视为字符串。这意味着表情符号的排序顺序由其底层 Unicode 值决定。

    3. 菲茨帕特里克量表

    菲茨帕特里克量表是人类肤色的分类系统,范围从 I 型(最浅)到 VI 型(最深)。Unicode 采用此量表在表情符号中引入肤色多样性。以下是修饰符与菲茨帕特里克量表的对应关系:

  • 🏻 (I 型): 轻度
  • 🏼(II 型):轻度至中度
  • 🏽(III 型):中等
  • 🏾(IV 型):中深色
  • 🏿(V 型):黑暗
  • 当使用这些修饰符对表情符号进行排序时,JavaScript 基本上根据肤色修饰符的数值对它们进行排序,这与菲茨帕特里克量表相对应。

    让我们看看实际效果

    以下是实际演示:

    // Array of emojis with skin-tone modifiers
    const emojis = ["👩🏿", "👩🏾", "👩🏽", "👩🏼", "👩🏻"];
    
    // Sort the array
    const sortedEmojis = emojis.sort();
    
    // Log the sorted array
    console.log(sortedEmojis); 
    // Output: ["👩🏻", "👩🏼", "👩🏽", "👩🏾", "👩🏿"]

    分解

  • .sort() 方法比较每个表情符号的 Unicode 值。
  • 肤色修饰符(🏻、🏼等)的 Unicode 值不断增加。
  • 这样表情符号就会从最浅(🏻)到最深(🏿)排序。
  • 有趣的实验

    让我们尝试一些变化并观察结果。

    1. 混合表情符号

    如果我们添加没有肤色修饰符的基本表情符号会发生什么?

    const mixedEmojis = ["👩🏿", "👩🏾", "👩", "👩🏽", "👩🏼", "👩🏻"];
    console.log(mixedEmojis.sort());

    **输出:**

    ["👩", "👩🏻", "👩🏼", "👩🏽", "👩🏾", "👩🏿"]

    这里,基本表情符号“👩”排在第一位,因为它的 Unicode 值最小,其次是排序后的肤色变体。

    2. 对其他表情符号组进行排序

    如果我们用修饰符(比如手势)对其他表情符号组进行排序会怎么样?

    const handEmojis = ["👍🏿", "👍🏽", "👍🏻", "👍🏼", "👍🏾"];
    console.log(handEmojis.sort());

    **输出:**

    ["👍🏻", "👍🏼", "👍🏽", "👍🏾", "👍🏿"]

    再次,表情符号是根据菲茨帕特里克量表排序的。

    Unicode 幕后

    为了更深入地理解排序行为,让我们检查每个表情符号的 Unicode 值:

    const emojiUnicode = emojis.map(e => e.codePointAt(0).toString(16));
    console.log(emojiUnicode);

    这将记录基本表情符号及其修饰符的 Unicode 值。您会注意到肤色修饰符的值逐渐增加。

    进一步阅读

  • Unicode 技术标准 #51
  • MDN: Array.prototype.sort()