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)