普通视图

发现新文章,点击刷新页面。
昨天以前首页

JavaScript 中的 sort 排序问题

2026年1月12日 22:12

在 JavaScript 中,以下两种写法是等价的:

写法一:

let fruits = ["banana", "apple", "cherry", "Apple"]  
fruits.sort()  
console.log(fruits) // ["Apple", "apple", "banana", "cherry"]  

写法二:

let fruits = ["banana", "apple", "cherry", "Apple"]
fruits.sort((a, b) => {
  return a > b ? 1 : -1
})
console.log(fruits)

sort 排序基本原理

因为 sort 函数默认是字符的 ASCII 码升序排列的。

比如:

'A'.charCode() // 65
'a'.charCode() // 97
'b'.charCode() // 98

因此如果是10和2排序的话,其实是'10'和'2'排序,'1'.charCode() 为 49,'2'.charCode() 为 50,导致出现 2 比 10 大,出现在 10 后面。

比如下面的代码:

let nums = [3, 10, 2]
nums.sort()
console.log('nums') // [10, 2, 3]

基础

那么问题来了,如果我想实现以下数组按照 appName 字典顺序降序排列怎么办?

let apps = [
  ['chrome', { cpu: 30, memory: 50 }],
  ['edge', { cpu: 30, memory: 20 }],
  ['firefox', { cpu: 80, memory: 90 }],
  ['safari', { cpu: 10, memory: 50 }],
]

注:chrome、edge 这些是 appName

欢迎在评论区解答。

进阶

再扩展一下,给定一个数组 sortRules,这个数组只能取 cpu 和 memory 两个值,可能是 0、1、2 个。

比如 sortRules 可能是:[]['cpu']['memory', 'cpu']['cpu', 'memory'] 等。

请实现先按照给定的 sortRules 的值依次升序排序,再按照 appName 降序排序。

比如 sortRules 是 ['cpu'],则排序结果是:

let apps = [
  ['safari', { cpu: 10, memory: 50 }],
  ['chrome', { cpu: 30, memory: 50 }],
  ['edge', { cpu: 30, memory: 20 }],
  ['firefox', { cpu: 80, memory: 90 }],
]

比如 sortRules 是 ['cpu', 'memory'],则排序结果是:

let apps = [
  ['safari', { cpu: 10, memory: 50 }],
  ['edge', { cpu: 30, memory: 20 }],
  ['chrome', { cpu: 30, memory: 50 }],
  ['firefox', { cpu: 80, memory: 90 }],
]

欢迎在评论区回复~

深入浅出 TinyEditor 富文本编辑器系列2:快速开始

2026年1月11日 10:46

你好,我是 Kagol,个人公众号:前端开源星球

这是《深入浅出 TinyEditor 富文本编辑器系列》的第2篇,完整的系列文章:

欢迎使用 TinyEditor - 一款基于 Quill 2.0 构建的强大富文本编辑器,提供了开箱即用的丰富模块和格式。本指南将帮助你快速高效地开始使用 TinyEditor。

架构概述

TinyEditor 采用模块化架构,通过自定义模块、格式和主题扩展了 Quill 的功能。核心结构包括:

模块架构.png

安装

基础设置

使用 npm 安装 TinyEditor:

npm install @opentiny/fluent-editor

该包以 ES 模块形式提供,包含所有必要的依赖,包括作为基础的 Quill 2.0。

项目结构

项目结构.png

基本用法

最小示例

创建一个具有最小配置的基础编辑器实例:

import FluentEditor from '@opentiny/fluent-editor'
 
const editor = new FluentEditor('#editor', {
  theme: 'snow'
})

包含多个模块的示例

这是一个展示配置多个模块的综合设置:

import FluentEditor, { CollaborationModule } from '@opentiny/fluent-editor'

// 引入协同编辑相关依赖
import * as Y from 'yjs'
import { Awareness } from 'y-protocols/awareness'
import { QuillBinding } from 'y-quill'
import { WebsocketProvider } from 'y-websocket'
import { IndexeddbPersistence } from 'y-indexeddb'
import QuillCursors from 'quill-cursors'

// 注册协同编辑模块
FluentEditor.register(
  'modules/collaborative-editing',
  CollaborationModule,
  true,
)

const editor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    toolbar: [
      [{ 'header': [1, 2, 3, false] }],
      ['bold', 'italic', 'underline', 'strike'],
      [{ 'color': [] }, { 'background': [] }],
      [{ 'list': 'ordered'}, { 'list': 'bullet' }],
      ['link', 'image', 'video'],
      ['clean']
    ],
    // 配置协同编辑模块
    'collaborative-editing': {
        deps: {
          Y,
          Awareness,
          QuillBinding,
          QuillCursors,
          WebsocketProvider,
          IndexeddbPersistence,
        },
        provider: {
          type: 'websocket',
          options: {
            serverUrl: 'wss://ai.opentiny.design/tiny-editor/',
            roomName: 'tiny-editor-document-demo-roomName',
          },
        },
        awareness: {
          state: {
            name: `userId:${Math.random().toString(36).substring(2, 15)}`,
            color: `rgb(${Math.floor(Math.random() * 255)},${Math.floor(Math.random() * 255)},${Math.floor(Math.random() * 255)})`,
          },
        },
    },
    'mathlive': true, // 需要引入 mathlive 相关依赖
    'syntax': true // 需要引入 highlight.js 相关依赖
  }
})

详细配置请参考文档:opentiny.github.io/tiny-editor…

可用模块

TinyEditor 提供了丰富的预注册模块集:

模块 描述 用法
toolbar 带有自定义处理器的增强工具栏 toolbar: { container: TOOLBAR_CONFIG }
image 支持格式化的高级图片处理 image: true
collaborative-editing 实时协作 参见上面的协作示例
mathlive LaTeX 数学公式 mathlive: true
syntax 代码语法高亮 syntax: true
emoji 表情选择器和支持 emoji: true
mention @提及功能 mention: true

配置选项

编辑器接受扩展了 Quill 选项的综合配置对象:

选项 类型 默认值 描述
modules IEditorModules {} 模块配置
scrollingContainer HTMLElement | string | null body 自定义滚动容器
autoProtocol boolean | string false 自动为链接添加协议
editorPaste any undefined 自定义粘贴处理
screenshot Partial<ScreenShotOptions> undefined 截图配置

快速开始模板

这是一个可用于快速原型设计的即用型 HTML 模板(可直接复制到 HTML 文件中运行):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>TinyEditor Quick Start</title>
  <style>
    #editor { 
      height: 400px; 
      border: 1px solid #ccc;
      padding: 10px;
    }
  </style>
  <!-- 引入 @opentiny/fluent-editor -->
  <script type="importmap">
    {
      "imports": {
        "@opentiny/fluent-editor": "https://unpkg.com/@opentiny/fluent-editor@3.18.3/index.es.js"
      }
    }
  </script>
  <!-- 引入 @opentiny/fluent-editor 样式 -->
  <link rel="stylesheet" href="https://unpkg.com/@opentiny/fluent-editor@3.18.3/style.css" />
</head>
<body>
  <div id="editor"></div>
  
  <script type="module">
    import FluentEditor from '@opentiny/fluent-editor'
    
    const editor = new FluentEditor('#editor', {
      theme: 'snow',
      modules: {
        toolbar: [
          ['bold', 'italic', 'underline'],
          [{ 'list': 'ordered'}, { 'list': 'bullet' }],
          ['link', 'image'],
          ['clean']
        ]
      }
    })
  </script>
</body>
</html>

效果图:

项目效果图.png

TinyEditor 类扩展了 Quill 的核心功能,同时保持与现有 Quill 配置的兼容性。这确保了现有 Quill 用户的平滑迁移路径,同时提供了对 TinyEditor 增强功能集的访问。

后续将全面介绍 TinyEditor 如何使用、设计架构、实现原理、二次开发等内容,点个关注,不迷路。

联系我们

GitHub:github.com/opentiny/ti…(欢迎 Star ⭐)

官网:opentiny.github.io/tiny-editor

个人博客:kagol.github.io/blogs/

小助手微信:opentiny-official

公众号:OpenTiny

❌
❌