2种常用方法
以下2种方法,只针对UTF-8编码,详细原因 请见后文的 关于编码。
// 方法1
function calculateUtf8ByteSize(str) {
// 非字符串 不作计算
if (typeof str !== 'string') return;
// 定义变量,用于累加字节数
let byteCount = 0;
// 遍历字符串中的每个字符
for (let i = 0, len = str.length; i < len; i++) {
// 获取当前字符的Unicode码
const charCode = str.charCodeAt(i);
// 根据字符的Unicode码,计算其占用的字节数
if (charCode <= 0x007F) {
byteCount += 1; // 在000000-00007F之间的字符(如字母),占用1个字节
} else if (charCode <= 0x07FF) {
byteCount += 2; // 在000080-0007FF之间的字符(如中文),占用2个字节
} else if (charCode <= 0xFFFF) {
byteCount += 3; // 000800-00FFFF之间的字符(如中文),占用3个字节
} else if (charCode <= 0x10FFFF){
byteCount += 4; // 010000-10FFFF之间的字符(如表情),占用4个字节
} else {
console.log('该字符超出Unicode编码范围');
}
}
return byteCount;
}
// 方法2
function calculateUtf8ByteSize(str) {
// 非字符串 不作计算
if (typeof str !== 'string') return;
// 创建一个TextEncoder实例
const encoder = new TextEncoder();
// 将字符串转换为UTF8编码的字节流(即Uint8Array数据)
const utf8 = encoder.encode(str);
return utf8.length;
}
注意:方法2代码量虽少,但其中的TextEncoder,在低版本浏览器可能存在兼容问题。
关于编码
ASCII编码
由美国制定的一套字符集,也是一种编码方式,主要用于英语环境,对应了英文字母、数字、特殊字符和控制字符 等等,它规定1个字符只占用1个字节。
Unicode字符
对应全世界语言符号的一套字符集(且都是唯一的),适用于全球环境(因此也称为万国码),但没有定义 1个字符占用多少字节。
UTF-16编码
一种编码方式,用于将 Unicode字符 编码为可存储的字节。这种编码方式规定,1个Unicode字符占用2或4个字节(绝大多数是2个字节),且无法兼容ASCII码。由于其占用固定的字节数,因此对内存会造成一定的浪费。
UTF-8编码
一种编码方式,用于将 Unicode字符 编码为可存储的字节。这种编码方式规定,1个Unicode字符占用1~4个字节(如上文JS代码所示),可兼容ASCII码。由于其使用更合理的内存分配,因此内存占用比UTF-16更小。
1)字符集 和 编码
Unicode仅仅是一套字符集,并非编码,因为它没有定义 每个字符在计算机中的存储方式(即占用多少字节),而ASCII、UTF-8、UTF-16才算是编码。
2)为何常听说“每个unicode字符占2个字节”
这种说法是不准确的。由于系统前期大多使用UTF-16对Unicode字符进行编码,加上绝大多数情况下的字符只占用2个字符,因此才传出这种说法。