码元和码点

简介: 在计算机中,字符存储依赖于其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个字节也就是超过了一个码元,所以在进行字符串处理的过程中会出现乱码的问题,通过添加三个处理码元码点的方法,就可以很好的解决这个问题。

目录
相关文章
|
7月前
|
机器学习/深度学习 人工智能 自然语言处理
大模型
大模型正重塑数字世界,以千亿级参数和深度学习技术驱动AI革命。它赋能内容生成、智能交互与知识服务,同时带来伦理、隐私与能耗挑战。未来需走向高效、可信、向善的可持续发展之路。
|
运维 监控 Go
Go语言微服务实战与最佳实践
【2月更文挑战第14天】本文将深入探讨使用Go语言进行微服务实战中的最佳实践,包括服务拆分、API设计、并发处理、错误处理、服务治理与监控等方面。通过实际案例和详细步骤,我们将分享如何在Go语言环境中构建高效、稳定、可扩展的微服务系统。
|
Web App开发 JavaScript 前端开发
从零开始,轻松打造个人化Chrome浏览器插件
从零开始,轻松打造个人化Chrome浏览器插件
487 0
|
机器学习/深度学习 自然语言处理 算法
《深度解析:批量、随机和小批量梯度下降的区别与应用》
梯度下降算法是优化模型参数的核心工具,包括批量梯度下降(BGD)、随机梯度下降(SGD)和小批量梯度下降(MBGD)。BGD使用全部数据计算梯度,收敛稳定但计算量大;SGD每次仅用一个样本,更新快但波动大;MBGD则取两者折中,使用小批量样本,兼具稳定性和效率。选择合适的变体需考虑数据规模、计算资源及精度要求。
902 1
|
JavaScript 前端开发 物联网
ArkTs的@Watch状态监听
@Watch是ArkUI框架中用于监听状态变量变化的核心工具,类似Vue的Watch机制。状态更新时,方法触发,通过`changedPropertyName`区分多个绑定变量。需与@State、@Prop、@Link等装饰器配合使用,顺序上须置于这些装饰器之后。实际开发中,@Watch常与@Link(跨组件双向同步)或@Provide(跨代组件同步)结合使用。例如,通过@Link接收父组件变量并监听变化,动态调整子组件状态;或利用@Provide定义全局变量,监听后更新整体进度状态。这种机制提升了组件间状态管理的灵活性与解耦性,助力开发者高效构建复杂应用,实现“一次开发,多端部署”的目标。
603 15
|
测试技术 持续交付 API
探索软件测试中的自动化:从新手到专家
在软件开发的世界中,测试是确保产品质量的关键步骤。本文将通过一个初学者的视角,介绍如何从零开始构建自动化测试框架,并逐步深入到更复杂的测试场景。我们将探讨自动化测试的优势、工具选择、以及如何有效地实施和扩展自动化测试策略。无论你是刚入门的软件测试新手,还是希望提升自动化测试技能的开发人员,这篇文章都将为你提供实用的指导和启示。
|
Ubuntu 安全 程序员
一文带你了解软件版本号
【9月更文挑战第3天】
5336 12
一文带你了解软件版本号
|
前端开发
【threejs教程】终于搞明白了!原来threejs中的透视相机这么简单!
【8月更文挑战第5天】深入学习threejs中的透视相机!
1219 2
【threejs教程】终于搞明白了!原来threejs中的透视相机这么简单!
|
JavaScript 前端开发
JS二进制转10进制、十六进制
JS二进制转10进制、十六进制 【8月更文挑战第9天】
649 6
|
Rust JavaScript 前端开发
将 Rust 程序编译为 WebAssembly 的知识与实践
本文记叙如何将一个 Rust 语言编译成可执行的 WebAssembly 文件。
732 0