我有一个javascript字符串,当从服务器以UTF-8发送时大约是500K。如何在JavaScript中说出它的大小?
我知道JavaScript使用的是UCS-2,所以这意味着每个字符有2个字节。但是,它是否依赖于JavaScript实现?或者在页面编码或内容类型?
答案 0 :(得分:57)
此函数将返回传递给它的任何UTF-8字符串的字节大小。
function byteCount(s) {
return encodeURI(s).split(/%..|./).length - 1;
}
JavaScript引擎可以在内部自由使用UCS-2或UTF-16。我所知道的大多数引擎都使用UTF-16,但无论做出什么选择,它只是一个不会影响语言特性的实现细节。
然而,ECMAScript / JavaScript语言本身根据UCS-2而不是UTF-16公开字符。
答案 1 :(得分:35)
如果你正在使用node.js,那么使用buffers会有一个更简单的解决方案:
function getBinarySize(string) {
return Buffer.byteLength(string, 'utf8');
}
有一个npm lib:https://www.npmjs.org/package/utf8-binary-cutter(来自你的忠实)
答案 2 :(得分:26)
String
值不依赖于实现,根据ECMA-262 3rd Edition Specification,每个字符代表一个单个16位UTF-16文本单元:
4.3.16字符串值
字符串值是String类型的成员,是一个 零或有限有序序列 更多16位无符号整数值。
注意虽然每个值通常 代表一个16位单位 UTF-16文本,语言没有 放置任何限制或要求 关于它们的价值观 16位无符号整数。
答案 3 :(得分:17)
使用 unescape js函数尝试此组合:
var byteAmount = unescape(encodeURIComponent(yourString)).length
完整编码过程示例:
var s = "1 a ф № @ ®"; //length is 11
var s2 = encodeURIComponent(s); //length is 41
var s3 = unescape(s2); //length is 15 [1-1,a-1,ф-2,№-3,@-1,®-2]
var s4 = escape(s3); //length is 39
var s5 = decodeURIComponent(s4); //length is 11
查看aditional屏幕 http://dl.dropbox.com/u/2086213/%3Dcoding%3D/js_utf_byte_length.png (我是新用户,所以我不能使用img标签)
答案 4 :(得分:12)
您可以使用Blob来获取字符串大小(以字节为单位)。
示例:
console.info(
new Blob(['']).size, // 4
new Blob(['']).size, // 4
new Blob(['']).size, // 8
new Blob(['']).size, // 8
new Blob(['I\'m a string']).size, // 12
// from Premasagar correction of Lauri's answer for
// strings containing lone characters in the surrogate pair range:
// https://stackoverflow.com/a/39488643/6225838
new Blob([String.fromCharCode(55555)]).size, // 3
new Blob([String.fromCharCode(55555, 57000)]).size // 4 (not 6)
);
答案 5 :(得分:6)
请注意,如果您定位node.js,则可以使用Buffer.from(string).length
:
var str = "\u2620"; // => "☠"
str.length; // => 1 (character)
Buffer.from(str).length // => 3 (bytes)
答案 6 :(得分:4)
<强>预ES6 强>
每个字符总是2个字节。不允许UTF-16,因为规范说“值必须是16位无符号整数”。由于UTF-16字符串可以使用3或4字节字符,因此违反2字节要求。至关重要的是,虽然不能完全支持UTF-16,但标准确实要求使用的两个字节字符是有效的UTF-16字符。换句话说,Pre-ES6 JavaScript字符串支持UTF-16字符的子集。
ES6及更高版本
每个字符2个字节,或每个字符5个或更多字节。其他尺寸起作用,因为ES6(ECMAScript 6)增加了对Unicode code point escapes的支持。使用unicode转义如下所示:\ u {1D306}
实用说明
这与特定引擎的内部实现无关。对于 例如,一些引擎使用数据结构和库 UTF-16支持,但它们提供的外部功能并非必须如此 完整的UTF-16支持。引擎也可以提供外部UTF-16 支持,但没有强制要求这样做。
对于ES6,实际上字符永远不会超过5 bytes long(转义点为2个字节,Unicode为3个字节) 代码点)因为最新版本的Unicode只有136,755 可能的字符,很容易适合3个字节。不过这是 技术上不受标准的限制,所以原则上是单一的 字符可以使用say,4个字节用于代码点和6个字节 总
此处用于计算字节大小的大多数代码示例似乎都没有考虑ES6 Unicode代码点转义,因此在某些情况下结果可能不正确。
答案 7 :(得分:2)
Lauri Oherd的回答适用于野外看到的大多数字符串,但如果字符串在代理对范围内包含单个字符0xD800到0xDFFF,则会失败。 E.g。
ToString()
这个较长的函数应该处理所有字符串:
byteCount(String.fromCharCode(55555))
// URIError: URI malformed
E.g。
function bytes (str) {
var bytes=0, len=str.length, codePoint, next, i;
for (i=0; i < len; i++) {
codePoint = str.charCodeAt(i);
// Lone surrogates cannot be passed to encodeURI
if (codePoint >= 0xD800 && codePoint < 0xE000) {
if (codePoint < 0xDC00 && i + 1 < len) {
next = str.charCodeAt(i + 1);
if (next >= 0xDC00 && next < 0xE000) {
bytes += 4;
i++;
continue;
}
}
}
bytes += (codePoint < 0x80 ? 1 : (codePoint < 0x800 ? 2 : 3));
}
return bytes;
}
它将正确计算包含代理项对的字符串的大小:
bytes(String.fromCharCode(55555))
// 3
可以将结果与Node的内置函数bytes(String.fromCharCode(55555, 57000))
// 4 (not 6)
进行比较:
Buffer.byteLength
答案 8 :(得分:1)
你可以试试这个:
var b = str.match(/[^\x00-\xff]/g);
return (str.length + (!b ? 0: b.length));
它对我有用。
答案 9 :(得分:1)
我正在使用嵌入式版本的V8引擎。 我测试了一个字符串。每步推1000个字符。 UTF-8。
首先测试单字节(8位,ANSI)字符“A”(十六进制:41)。 第二次测试用双字节字符(16位)“Ω”(十六进制:CE A9)和 第三次测试用三字节字符(24位)“☺”(十六进制:E2 98 BA)。
在所有三种情况下,设备打印内存不足 888 000个字符并使用ca.内存26 348 kb。
结果:字符不是动态存储的。而不是只有16位。 - 好吧,也许只针对我的情况(嵌入式128 MB RAM设备,V8引擎C ++ / QT) - 字符编码与javascript引擎的ram大小无关。例如。 encodingURI等仅适用于高级数据传输和存储。
嵌入与否,事实是这些字符不仅存储在16bit中。 不幸的是,我没有100%回答,Javascript在低级别区域做了什么。 顺便说一句。我用一个字符“A”的数组测试了相同的(上面的第一个测试)。 每一步推1000件。 (完全相同的测试。只是将字符串替换为数组)并且系统在使用10 416 KB并且数组长度为1 337 000之后带来内存(想要的)。 所以,javascript引擎不是简单的限制。这是一种更复杂的。
答案 10 :(得分:1)
这些是我使用的3种方式:
TextEncoder()
(new TextEncoder().encode("myString")).length)
斑点
new Blob(["myString"]).size)
缓冲区
Buffer.byteLength("myString", 'utf8'))
答案 11 :(得分:1)
Blob 接口的 size 属性以字节为单位返回 Blob 或文件的大小。
const getStringSize = (s) => new Blob([s]).size;
答案 12 :(得分:0)
JavaScript String中的单个元素被视为单个UTF-16代码单元。也就是说,字符串字符以16位(1代码单元)存储,16位等于2字节(8位= 1字节)。
charCodeAt()
方法可用于返回0到65535之间的整数,表示给定索引处的UTF-16代码单元。
codePointAt()
可用于返回Unicode字符的整个代码点值,例如UTF-32。
当UTF-16字符无法在单个16位代码单元中表示时,它将具有代理对,因此使用两个代码单元(2 x 16位= 4字节)
有关不同的编码及其代码范围,请参阅Unicode encodings。