前端中JS的字符编码及常用操作字符API
zhezhongyun 2024-12-10 22:00 58 浏览
在 JavaScript 中,Unicode 编码方式用于表示字符,包括中文字符。Unicode 是一个标准的字符编码系统,为世界上几乎所有的字符都定义了唯一的编号,以便在计算机中进行交换和处理。本文将着重讨论 JavaScript 中的字符编码。关于其前端数据流的一些编码工作可以移步这里: JS处理文件数据的API
字符集简介(Unicode)
Unicode 是一个字符编码标准,定义了世界上几乎所有字符的唯一编号,使得在计算机中交换和处理文本变得更加统一和可靠。Unicode 字符集包含了数十万个字符,覆盖了几乎所有的书写系统、符号、标点符号、表情符号等。以下是 Unicode 字符集的详细内容:
- 基本多文种平面(Basic Multilingual Plane,BMP): 这是Unicode字符集中最常用和最广泛使用的部分,包含了U+0000至U+FFFF的字符范围,共计65536个字符。其中包括了:
- 基本拉丁字母(Basic Latin):包含英文字母、数字、标点符号等,U+0000至U+007F。
- 拉丁字母补充-1(Latin-1 Supplement):包含一些欧洲语言特有的字符,U+0080至U+00FF。
- 拉丁字母扩展-A、B、C、D(Latin Extended-A、B、C、D):包含更多欧洲语言的字符,U+0100至U+024F。
- 基本希腊字母(Greek and Coptic):包含希腊字母,U+0370至U+03FF。
- 基本西里尔字母(Cyrillic):包含西里尔字母,U+0400至U+04FF。
- 基本汉字(CJK Unified Ideographs):包含最常用的汉字,U+4E00至U+9FFF。
- 以及其他语言的字符,如希伯来文、阿拉伯文、泰文、韩文、日文假名等。
- 辅助平面(Supplementary Planes): 除了基本多文种平面之外,Unicode还定义了16个辅助平面,分别从U+010000至U+10FFFF,每个辅助平面包含65536个字符,共计1,114,112个字符。辅助平面中包含了更多不常用的字符,特殊符号、历史上的书写系统、emoji表情符号等。
- 保留区域(Private Use Area): Unicode还保留了一部分区域,供个人或组织自行定义字符。这些字符不在Unicode官方标准中定义,只在特定的上下文中有意义。
- 非字符代码点(Noncharacter Code Points): Unicode还定义了一些非字符代码点,这些代码点没有对应的字符表示,用于特殊目的,如表示无效的编码或保留未来使用。
注: JavaScript 中的使用的 Unicode 编码方式主要有两种:UTF-16 和 UTF-8。
UTF-16
UTF-16(16-bit Unicode Transformation Format)是JavaScript中使用的主要字符编码方式。在UTF-16中,每个字符由一个或两个16位的代码单元(code unit)表示。对于 ASCII 字符和大部分常用字符,UTF-16使用一个16位的代码单元表示;对于一些较少使用的字符(如一些特殊的中文字符),UTF-16使用两个16位的代码单元表示,合称为“代理对”(surrogate pair)。UTF-16 代理对的范围为:从 U+D800 到 U+DFFF。注意,这个范围是不可用的(reserved),并且不能用于表示 Unicode 字符,因此UTF-16的可用编码范围是从 U+0000到 U+D7FF 和从 U+E000 到 U+10FFFF。这样留出了一个区间用于表示代理对。
注意:无法打印显示不代表不表示字符,如 U+E000 - U+FFFF 在Unicode编码中属于字形图形(Private Use Area)范围,有一些字符可以在浏览器中打印出来,但需要注意的是这些字符的显示效果可能会因浏览器、操作系统和字体的差异而有所不同。这些字符没有统一的含义,通常用于特定的定制和私有应用场景
UTF-16代理对编码规则如下:
- 高位代理(High Surrogate):U+D800到U+DBFF,共1024个代码点。 高位代理的二进制范围为:1101 10xx xxxx xxxx
- 低位代理(Low Surrogate):U+DC00到U+DFFF,共1024个代码点。 低位代理的二进制范围为:1101 11xx xxxx xxxx
在JavaScript中,可以使用 \u 转义序列来表示UTF-16编码的字符,后跟四个十六进制数字。例如,中文字符 “你” 对应的UTF-16编码是U+4F60,可以用 \u4F60 来表示。
js// 单个16位代码单元表示的字符
const chineseCharacter = '\u4F60'; // 表示中文字符"你"
console.log(chineseCharacter); // 输出:你
// 双个16位代码单元表示的字符(使用高低代理对表示)
const chineseCharacter = '\ud841\udf0e''; // 表示中文字符""
console.log(chineseCharacter); // 输出:UTF-8
UTF-8(8-bit Unicode Transformation Format)是一种变长的编码方式,它可以用一个或多个8位字节(byte)来表示一个字符。UTF-8编码的主要特点是使用1到4个字节来表示不同范围的Unicode字符,使得它能够适应不同类型的文本,并且兼容ASCII字符。对于一般的中文字符,多数是使用3个字节来表示。
UTF-8编码规则如下:
单字节编码:
- 对于ASCII字符(U+0000至U+007F),UTF-8使用单个字节来表示,字节的最高位为0,其余7位表示ASCII字符的编码。
多字节编码: 对于非ASCII字符(U+0080及以上的字符),UTF-8使用多个字节表示。多字节的编码规则如下:
- 2字节编码:第一个字节的前两位为“110”,第二个字节的前两位为“10”,剩下的5+6位用来存储Unicode字符的编码。
- 3字节编码:第一个字节的前三位为“1110”,第二、第三个字节的前两位为“10”,剩下的4+6+6位用来存储Unicode字符的编码。
- 4字节编码:第一个字节的前四位为“11110”,第二、第三、第四个字节的前两位为“10”,剩下的3+6+6+6位用来存储Unicode字符的编码。
字符编码常用的API
1. String.fromCharCode
根据给定码点,查找相对应的字符,注意:该Api只支持 16 位 Unicode 码点,也即是到0 ~ 65535 范围的字符,可能无法正确处理某些特殊字符。
jsString.fromCharCode('65532') // '?'
String.fromCharCode('2312') // '?'
String.fromCharCode(21029234827265) // '态' 超出范围时 会保留后两个字节的数据
// 21029234827265 二进制表示为 100110010000001000000000100100110000000000001
// 后两个字节 为 '0110000000000001' 转成10进制为 24577
// 所以 String.fromCharCode(21029234827265) === String.fromCharCode(24577) // '态'
2. String.fromCodePoint
根据给定码点,查找相对应的字符,注意:该Api支持所有Unicode字符的范围。
jsString.fromCodePoint('132878') // 超过了 0xffff范围
String.fromCodePoint('24577') // 态 没超过了 0xffff范围
下面三个 API 都是根据字符查找相关的码点位置,有所区别
3. String.prototype.charCodeAt
取指定索引处字符的 Unicode 码点值。 注意:该Api只支持 16 位 Unicode 码点,也即是到0 ~ 65535 范围的字符,并且取得字符位置的编码方式是以UTF-16格式获取,如下。
js // 没超过了 0xffff范围
String.prototype.charCodeAt.call('态',0) // 24577 0x6001
// 超过了 0xffff范围
String.prototype.charCodeAt.call('',0) // 55361 0xd841
String.prototype.charCodeAt.call('',1) // 57102 0xdf0e
4. String.prototype.charAt
取指定索引处字符的 Unicode 码点值。 注意:该Api只能按照 16 位 去取值,只支持 16 位 Unicode 码点的一次性取值。
js// 超过了 0xffff范围
String.prototype.charAt.call('$%^&*',0) // '\uD841' 与 String.prototype.charCodeAt.call('',0) 位置相同
String.prototype.charAt.call('$%^&*',1) // ''\uDF0E' 与 String.prototype.charCodeAt.call('',1) 位置相同
// 没超过了 0xffff范围
String.prototype.charAt.call('$%^&*',2) // '#39;
5. String.prototype.codePointAt
获取指定索引处的字符。 来处理更大范围的 Unicode 码点值,可以包含整个unicode编码的字符, 注意:该Api支持所有 Unicode 字符的范围。
jsString.prototype.codePointAt.call('') // 132878 超过了 0xffff范围
String.prototype.codePointAt.call('态') // 24577 没超过了 0xffff范围
UniCode字符到UTF-16转换
由于需要在浏览器显示相关的Unicode字符,使用类似 '\u6001' 这种形式,我们需要对Unicode上的所有码点进行处理,方式有很多,这里使用较为简单的一种方式实现,如下:
jsfunction getCodePointByCharsToChar(chars){
const res = [];
for(let i =0; i<chars.length;i++ ){
const high =chars[i].charCodeAt(0).toString(16);
if(chars[i]){
if(chars[i].codePointAt()>0xffff){
const low =chars[i].charCodeAt(1).toString(16);
res.push(
`\u${'0'.repeat(4-high.length)}${high}\u${'0'.repeat(4-low.length)}${low}`
);
}else{
res.push(
`\u${'0'.repeat(4-high.length)}${high}`
);
}
}
}
return res;
}
// 双字节字符表示
getCodePointByCharsToChar('今天是个好天气') // ['\u4eca', '\u5929', '\u662f', '\u4e2a', '\u597d', '\u5929', '\u6c14']
// 多字节字符表示
getCodePointByCharsToChar('') // ['\ud841', '\udf0e', '\ud841', '\udf0e', '\ud841', '\udf0e', '\ud841', '\udf0e', '\ud841', '\udf0e', '\ud841', '\udf0e']
总结: 关于前端中常常使用的字符集相关的API介绍已经结束,关于Javascript字符集的一些想法和问题,可以评论区留言。
相关推荐
- Python入门学习记录之一:变量_python怎么用变量
-
写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...
- python变量命名规则——来自小白的总结
-
python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...
- Python入门学习教程:第 2 章 变量与数据类型
-
2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...
- 绘制学术论文中的“三线表”具体指导
-
在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...
- Python基础语法知识--变量和数据类型
-
学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...
- 一文搞懂 Python 中的所有标点符号
-
反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...
- Python变量类型和运算符_python中变量的含义
-
别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...
- 从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序
-
在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...
- Python中下划线 ‘_’ 的用法,你知道几种
-
Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...
- 解锁Shell编程:变量_shell $变量
-
引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...
- 一文学会Python的变量命名规则!_python的变量命名有哪些要求
-
目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...
- 更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for
-
src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...
- C++第五课:变量的命名规则_c++中变量的命名规则
-
变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....
- Rust编程-核心篇-不安全编程_rust安全性
-
Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...
- 探秘 Python 内存管理:背后的神奇机制
-
在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 教程 (33)
- HTML 简介 (35)
- HTML 实例/测验 (32)
- HTML 测验 (32)
- JavaScript 和 HTML DOM 参考手册 (32)
- HTML 拓展阅读 (30)
- HTML文本框样式 (31)
- HTML滚动条样式 (34)
- HTML5 浏览器支持 (33)
- HTML5 新元素 (33)
- HTML5 WebSocket (30)
- HTML5 代码规范 (32)
- HTML5 标签 (717)
- HTML5 标签 (已废弃) (75)
- HTML5电子书 (32)
- HTML5开发工具 (34)
- HTML5小游戏源码 (34)
- HTML5模板下载 (30)
- HTTP 状态消息 (33)
- HTTP 方法:GET 对比 POST (33)
- 键盘快捷键 (35)
- 标签 (226)
- opacity 属性 (32)
- transition 属性 (33)
- 1-1. 变量声明 (31)
