码元和码点

简介: 在计算机中,字符存储依赖于其ASCII编码值。JS中,每个字符占用16位(2字节)的空间,称为码元,范围0-65535。当字符所需空间超限时,JS使用两个码元表示,总称码点。处理特殊字符如表情时,需自定义方法以正确识别码点,避免乱码,确保字符串操作准确无误。

码元和码点

1.介绍码元和码点

​ 在计算机中存储字符不是存储一个真正的字符,而是存储这个字符对应的ascll编码值。在js中,一个字符占16位空间也就是2个字节,而这个空间就称之为码元,一个码元的存储空间是0-2的16次方,也就是65535,而在现实生活中我们的文字绝不只这点于是想要存储一个字符所占空间大于65535的话,js就会开两个空间给这个字符,而这个字符所占的全部空间就称之为码点。

2.码元码点的实际用途

在js中,我们通过字符串的length属性实际上是在访问这个字符串所占的码元。

const string = "😭🦐"
console.log(string.length); // 4

所以在开发中我们遇到表情这种占两个码元的字符时,处理起来会有点问题,如:

const string = "😭🦐"
console.log(string.slice(0,1)) // 输出乱码

因为slice方法实际上也是根据字符的码元进行截取,而字符串里的一个字符是占两个码元的所以当我们想截取第一个字符的时候只截取到了他第一个码元,还有一个码元没有截取到,所以会导致乱码。

解决办法就是在字符串原型上添加几个专门处理表情等字符的方法。

一,方法一

​ 在字符串原型上添加pointLength方法,用于获取字符串的码点数量

String.prototype.pointLength = function () {
   
  let len = 0;
  for (let i = 0; i < this.length; ) {
   
    len++;
    const t = this.codePointAt(i);
    i += t > 0xffff ? 2 : 1;
  }
  return len;
};

二,方法二

​ 在字符串原型上添加pointAt方法,用于获取字符串中指定码点索引的字符。

String.prototype.pointAt = function (index) {
   
  let currentIndex = 0;
  for (let i = 0; i < this.length; ) {
   
    if (currentIndex === index) {
   
      const code = this.codePointAt(i);
      return String.fromCodePoint(code);
    }
    currentIndex++;
    const point = this.codePointAt(i);
    i += point > 0xffff ? 2 : 1;
  }
};

三,方法三

​ 在字符串原型上添加pointSlice方法,用于截取指定码点索引的字符。

String.prototype.pointSlice = function (start, end) {
   
  let result = "";

  for (let i = start; i < this.pointLength() && i < end; i++) {
   
    result += this.pointAt(i);
  }
  return result;
};

添加完这三个方法后,以后处理这种表情字符串就容易多了。

const a = "🦐😭😠🏃";

console.log(a.pointLength()); // 4
console.log(a.pointAt(1)); // 🦐
console.log(a.pointSlice(2, 3)); // 😠

3.结语

码元与码点的问题主要会出现在一些偏僻子,表情等字符中,因为这些字符的存储空间超过了2个字节也就是超过了一个码元,所以在进行字符串处理的过程中会出现乱码的问题,通过添加三个处理码元码点的方法,就可以很好的解决这个问题。

目录
相关文章
|
12月前
|
机器学习/深度学习 自然语言处理 算法
《深度解析:批量、随机和小批量梯度下降的区别与应用》
梯度下降算法是优化模型参数的核心工具,包括批量梯度下降(BGD)、随机梯度下降(SGD)和小批量梯度下降(MBGD)。BGD使用全部数据计算梯度,收敛稳定但计算量大;SGD每次仅用一个样本,更新快但波动大;MBGD则取两者折中,使用小批量样本,兼具稳定性和效率。选择合适的变体需考虑数据规模、计算资源及精度要求。
764 1
|
测试技术 持续交付 API
探索软件测试中的自动化:从新手到专家
在软件开发的世界中,测试是确保产品质量的关键步骤。本文将通过一个初学者的视角,介绍如何从零开始构建自动化测试框架,并逐步深入到更复杂的测试场景。我们将探讨自动化测试的优势、工具选择、以及如何有效地实施和扩展自动化测试策略。无论你是刚入门的软件测试新手,还是希望提升自动化测试技能的开发人员,这篇文章都将为你提供实用的指导和启示。
|
6月前
|
缓存 人工智能 算法
《解构WebSocket断网重连:指数退避算法的前端工业级实践指南》
本文聚焦前端领域WebSocket断网重连难题,深入解析指数退避算法的工业级实践路径。首先指出传统固定间隔、线性递增重连策略在效率与服务器压力间的失衡问题,随后拆解指数退避算法“指数增长+随机抖动+最大间隔约束”的核心逻辑。文章详细阐述算法与WebSocket生命周期的适配要点,包括重连时机甄别、状态原子化管理,还介绍网络状态感知融合、重连超时设置、数据缓存恢复等优化方向,并结合大型在线协作平台案例验证效果,同时梳理开发者常见误区与避坑方法,最后展望算法与AI、跨端场景结合的未来方向,为前端构建稳健实时应用提供完整指南。
286 8
|
前端开发 JavaScript 搜索推荐
|
10月前
|
JavaScript 前端开发 物联网
ArkTs的@Watch状态监听
@Watch是ArkUI框架中用于监听状态变量变化的核心工具,类似Vue的Watch机制。状态更新时,方法触发,通过`changedPropertyName`区分多个绑定变量。需与@State、@Prop、@Link等装饰器配合使用,顺序上须置于这些装饰器之后。实际开发中,@Watch常与@Link(跨组件双向同步)或@Provide(跨代组件同步)结合使用。例如,通过@Link接收父组件变量并监听变化,动态调整子组件状态;或利用@Provide定义全局变量,监听后更新整体进度状态。这种机制提升了组件间状态管理的灵活性与解耦性,助力开发者高效构建复杂应用,实现“一次开发,多端部署”的目标。
545 15
|
Ubuntu 安全 程序员
一文带你了解软件版本号
【9月更文挑战第3天】
4781 12
一文带你了解软件版本号
|
JavaScript 前端开发
JavaScript的`apply`方法:函数的“应用”与“调用”
JavaScript的`apply`方法:函数的“应用”与“调用”
|
JavaScript 前端开发
JS二进制转10进制、十六进制
JS二进制转10进制、十六进制 【8月更文挑战第9天】
590 6
|
Rust JavaScript 前端开发
将 Rust 程序编译为 WebAssembly 的知识与实践
本文记叙如何将一个 Rust 语言编译成可执行的 WebAssembly 文件。
691 0
|
编解码 前端开发 UED
前端需要完完全全掌握的这些布局方案
前端需要完完全全掌握的这些布局方案