首頁 >web前端 >js教程 >Javascript 計算字串在localStorage中所佔位元組數_javascript技巧

Javascript 計算字串在localStorage中所佔位元組數_javascript技巧

WBOY
WBOY原創
2016-05-16 15:35:571275瀏覽

最近專案有個需求要用js計算一串字串寫入到localStorage裡所佔的內存,眾所周知的,js是使用Unicode編碼的。而Unicode的實作有N種,其中用的最多的就是UTF-8和UTF-16。因此本文只對這兩種編碼進行討論。

下面這個定義是摘自維基百科(http://zh.wikipedia.org/zh-cn/UTF-8),做了部分刪減。

UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字符編碼,可以表示Unicode標準中的任何字符,且其編碼中的第一個字節仍與ASCII相容,使用一至四個位元組為每個字元編碼

其編碼規則如下:

字元代碼在000000 – 00007F之間的,用一個位元組編碼;

000080 – 0007FF之間的字元用兩個位元組;
000800 – 00D7FF 和 00E000 – 00FFFF之間的用三個字節,註: Unicode在範圍 D800-DFFF 中不存在任何字元;
010000 – 10FFFF之間的用4個位元組。

而UTF-16 則是定長的字元編碼,大部分字元使用兩個位元組編碼,字元代碼超出 65535 的使用四個位元組,如下:

000000 – 00FFFF 兩個位元組;
010000 – 10FFFF 四個位元組。

一開始認為既然頁面用的是UTF-8編碼,那麼存入localStorage的字串,應該也是用UTF-8編碼的。但後來測試發現,明明計算出來的size是不到5MB,存入localStorage卻丟異常了。想了想,頁面的編碼是可以改的。如果localStorage依照頁面的編碼存字串,不就亂套了?瀏覽器應該都是使用UTF-16編碼的。用UTF-16編碼計算出5MB的字串,果然順利寫進去了。超過則失敗了。

好了,附上程式碼實作。計算規則就是上面寫的,為了計算速度,把兩個for迴圈分開寫了。

/**
   * 计算字符串所占的内存字节数,默认使用UTF-8的编码方式计算,也可制定为UTF-16
   * UTF-8 是一种可变长度的 Unicode 编码格式,使用一至四个字节为每个字符编码
   *
   * 000000 - 00007F(128个代码)   0zzzzzzz(00-7F)               一个字节
   * 000080 - 0007FF(1920个代码)   110yyyyy(C0-DF) 10zzzzzz(80-BF)       两个字节
   * 000800 - 00D7FF
    00E000 - 00FFFF(61440个代码)  1110xxxx(E0-EF) 10yyyyyy 10zzzzzz      三个字节
   * 010000 - 10FFFF(1048576个代码) 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz 四个字节
   *
   * 注: Unicode在范围 D800-DFFF 中不存在任何字符
   * {@link http://zh.wikipedia.org/wiki/UTF-8}
   *
   * UTF-16 大部分使用两个字节编码,编码超出 65535 的使用四个字节
   * 000000 - 00FFFF 两个字节
   * 010000 - 10FFFF 四个字节
   *
   * {@link http://zh.wikipedia.org/wiki/UTF-16}
   * @param {String} str
   * @param {String} charset utf-8, utf-16
   * @return {Number}
   */
  var sizeof = function(str, charset){
    var total = 0,
      charCode,
      i,
      len;
    charset = charset ? charset.toLowerCase() : '';
    if(charset === 'utf-16' || charset === 'utf16'){
      for(i = 0, len = str.length; i < len; i++){
        charCode = str.charCodeAt(i);
        if(charCode <= 0xffff){
          total += 2;
        }else{
          total += 4;
        }
      }
    }else{
      for(i = 0, len = str.length; i < len; i++){
        charCode = str.charCodeAt(i);
        if(charCode <= 0x007f) {
          total += 1;
        }else if(charCode <= 0x07ff){
          total += 2;
        }else if(charCode <= 0xffff){
          total += 3;
        }else{
          total += 4;
        }
      }
    }
    return total;
  }

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn