JavaScriptstring中有多less个字节?
我有一个从UTF-8的服务器发送约500K的JavaScriptstring。 我怎样才能告诉它的大小在JavaScript中?
我知道JavaScript使用UCS-2,所以这意味着每个字符2个字节。 但是,它依赖于JavaScript的实现吗? 或在页面编码或可能是内容types?
String
值不依赖于实现,根据ECMA-262第三版规范 ,每个字符表示UTF-16文本的单个16位单元 :
4.3.16string值
string值是Stringtypes的成员,是零个或多个16位无符号整数值的有限有序序列。
注意虽然每个值通常表示UTF-16文本的单个16位单元,但除了它们是16位无符号整数之外,该语言对这些值没有任何限制或要求。
该函数将返回您传递给它的任何UTF-8string的字节大小。
function byteCount(s) { return encodeURI(s).split(/%..|./).length - 1; }
资源
JavaScript引擎可以在内部自由使用UCS-2或UTF-16。 我所知道的大多数引擎都使用UTF-16,但无论他们做了什么select,这只是一个实现细节,不会影响语言的特性。
但是,ECMAScript / JavaScript语言本身是根据UCS-2而不是UTF-16公开字符的。
资源
如果你使用node.js,使用缓冲区有一个更简单的解决scheme:
function getBinarySize(string) { return Buffer.byteLength(string, 'utf8'); }
有一个npm的lib: https : //www.npmjs.org/package/utf8-binary-cutter (从你的忠实的)
尝试使用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
见习惯屏幕http://dl.dropbox.com/u/2086213/%3Dcoding%3D/js_utf_byte_length.png (我是一个新用户,所以我不能使用img标签)
UTF-8使用每码点1到4个字节对字符进行编码。 正如CMS在接受的答案中指出的,JavaScript将使用16位(2个字节)在内部存储每个字符。
如果通过循环parsingstring中的每个字符并计算每个代码点使用的字节数,然后将总计数乘以2,那么您应该为该UTF-8编码的string提供JavaScript的内存使用量(以字节为单位)。 也许是这样的:
getStringMemorySize = function( _string ) { "use strict"; var codePoint , accum = 0 ; for( var stringIndex = 0, endOfString = _string.length; stringIndex < endOfString; stringIndex++ ) { codePoint = _string.charCodeAt( stringIndex ); if( codePoint < 0x100 ) { accum += 1; continue; } if( codePoint < 0x10000 ) { accum += 2; continue; } if( codePoint < 0x1000000 ) { accum += 3; } else { accum += 4; } } return accum * 2; }
例子:
getStringMemorySize( 'I' ); // 2 getStringMemorySize( '❤' ); // 4 getStringMemorySize( '𠀰' ); // 8 getStringMemorySize( 'I❤𠀰' ); // 14
你可以试试这个:
var b = str.match(/[^\x00-\xff]/g); return (str.length + (!b ? 0: b.length));
它为我工作。
Lauri Oherd的答案适用于大多数在野外看到的string,但是如果string在代理对范围0xD800到0xDFFF中包含单个字符,将会失败。 例如
byteCount(String.fromCharCode(55555)) // URIError: URI malformed
这个更长的函数应该处理所有string
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
它将正确计算包含代理对的string的大小:
bytes(String.fromCharCode(55555, 57000)) // 4 (not 6)
结果可以与Node的内置函数Buffer.byteLength
:
Buffer.byteLength(String.fromCharCode(55555), 'utf8') // 3 Buffer.byteLength(String.fromCharCode(55555, 57000), 'utf8') // 4 (not 6)
我正在使用V8引擎的embedded式版本。 我testing过一个string。 每步推送1000个字符。 UTF-8。
首先testing单字节(8位,ANSI)字符“A”(hex:41)。 用双字节字符(16位)“Ω”(hex:CE A9)进行第二次testing,用三字节字符(24位)“☺”(hex:E2 98 BA)进行第二次testing。
在所有这三种情况下,设备都会打印888000个字符的内存并使用ca. RAM中26 348 kb。
结果:字符不会dynamic存储。 而不是只有16位。 – 好吧,也许只适用于我的情况(embedded式128 MB RAM设备,V8引擎C ++ / QT) – 字符编码与JavaScript引擎的内存大小无关。 例如encodingURI等仅用于高级数据传输和存储。
embedded与否,其实这些字符不仅存储在16bit中。 不幸的是,我没有100%的答案,Javascript在低级区域做了什么。 顺便说一句。 我用一个字符“A”的数组testing了相同的(上面的第一个testing)。 推动1000个项目每一步。 (完全相同的testing,只是将stringreplace为数组)而且系统在10 416 KB使用和数组长度为1 337 000之后会导致内存不足(想要)。因此,JavaScript引擎不是简单的限制。 这是一种更复杂的。
JavaScriptstring的大小是
- ES6之前 :每个字符2个字节
- ES6及更高版本:每个字符2个字节,或每个字符5个或更多字节
预ES6
每个字符总是2个字节。 UTF-16是不允许的,因为规范说“值必须是16位无符号整数”。 由于UTF-16string可以使用3或4个字节的字符,因此违反了2字节的要求。 至关重要的是,虽然UTF-16不能完全支持,但标准要求使用的两个字节字符是有效的UTF-16字符。 换句话说,ES6之前的JavaScriptstring支持UTF-16字符的一个子集。
ES6及更高版本
每个字符2个字节,或每个字符5个或更多字节。 由于ES6(ECMAScript 6)增加了对Unicode代码点转义的支持,因此额外的大小起作用。 使用unicode转义看起来像这样:\ u {1D306}
实用笔记
-
这并不涉及特定引擎的内部实现。 例如,一些引擎使用具有完整UTF-16支持的数据结构和库,但是它们在外部提供的内容不一定是完整的UTF-16支持。 另外一个引擎也可以提供外部的UTF-16支持,但并没有强制要求这样做。
-
对于ES6来说,由于最新版本的Unicode只有136755个可能的字符,容易分成3个字节,所以实际上字符长度不会超过5个字节(2个字节为逃逸点+3个字节为Unicode码点)。 然而,这在技术上不受标准的限制,因此原则上单个字符可以使用4个字节的代码点和总共6个字节。
-
这里用于计算字节大小的大多数代码示例似乎没有考虑ES6 Unicode代码点转义,所以在某些情况下结果可能不正确。
JavaScript String中的单个元素被认为是单个UTF-16代码单元。 也就是说,string字符以16位(1代码单元)存储,而16位等于2字节(8位= 1字节)。
charCodeAt()
方法可用于返回0到65535之间的整数,表示给定索引处的UTF-16代码单元。
codePointAt()
可用于返回Unicode字符的整个代码点值,例如UTF-32。
当UTF-16字符不能用单个16位代码单元表示时,它将具有代理对,因此使用两个代码单元(2×16位= 4个字节)
查看不同编码及其代码范围的Unicode编码 。
请注意,如果您的目标是node.js,则可以使用Buffer.from(string).length
:
var str = "\u2620"; // => "☠" str.length; // => 1 (character) Buffer.from(str).length // => 3 (bytes)