JavaScript字符串中有多少字节?

时间:2010-02-08 04:09:03

标签: javascript string size byte

我有一个javascript字符串,当从服务器以UTF-8发送时大约是500K。如何在JavaScript中说出它的大小?

我知道JavaScript使用的是UCS-2,所以这意味着每个字符有2个字节。但是,它是否依赖于JavaScript实现?或者在页面编码或内容类型?

13 个答案:

答案 0 :(得分:57)

此函数将返回传递给它的任何UTF-8字符串的字节大小。

function byteCount(s) {
    return encodeURI(s).split(/%..|./).length - 1;
}

Source

JavaScript引擎可以在内部自由使用UCS-2或UTF-16。我所知道的大多数引擎都使用UTF-16,但无论做出什么选择,它只是一个不会影响语言特性的实现细节。

然而,ECMAScript / JavaScript语言本身根据UCS-2而不是UTF-16公开字符。

Source

答案 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)

JavaScript字符串的大小为

  • Pre-ES6 :每个字符2个字节
  • ES6 及更高版本:每个字符2个字节, 或每个字符5个或更多字节

<强>预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种方式:

  1. TextEncoder()

    (new TextEncoder().encode("myString")).length)

  2. 斑点

    new Blob(["myString"]).size)

  3. 缓冲区

    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