Javascript 计算字符串在localStorage中所占字节数


Posted in Javascript onOctober 21, 2015

最近项目有个需求要用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;
  }
Javascript 相关文章推荐
JAVASCRIPT style 中visibility和display之间的区别
Jan 22 Javascript
Javascript的一种模块模式
Sep 08 Javascript
Javascript delete 引用类型对象
Nov 01 Javascript
jQuery链使用指南
Jan 20 Javascript
jQuery实现列表的全选功能
Mar 18 Javascript
javascript实现一个数值加法函数
Jun 26 Javascript
快速使用Bootstrap搭建传送带
May 06 Javascript
浅谈js的解析顺序 作用域 严格模式
Oct 23 Javascript
JavaScript类数组对象转换为数组对象的方法实例分析
Jul 24 Javascript
angularjs1.5 组件内用函数向外传值的实例
Sep 30 Javascript
vue实现的封装全局filter并统一管理操作示例
Feb 02 Javascript
vue 动态添加class,三个以上的条件做判断方式
Nov 02 Javascript
深入解析JavaScript的闭包机制
Oct 20 #Javascript
JavaScript中字面量与函数的基本使用知识
Oct 20 #Javascript
JavaScript基本的输出和嵌入式写法教程
Oct 20 #Javascript
javascript省市级联功能实现方法实例详解
Oct 20 #Javascript
基于JavaScript实现移动端TAB触屏切换效果
Oct 20 #Javascript
js点击文本框后才加载验证码实例代码
Oct 20 #Javascript
javascript实现状态栏中文字动态显示的方法
Oct 20 #Javascript
You might like
经典的星际争霸,满是回忆的BGM
2020/04/09 星际争霸
完善CodeIgniter在IDE中代码提示功能的方法
2014/07/19 PHP
PHP实现的堆排序算法详解
2017/08/17 PHP
jQuery 使用手册(五)
2009/09/23 Javascript
15个款优秀的 jQuery 图片特效插件推荐
2011/11/21 Javascript
使用jquery实现图文切换效果另加特效
2013/01/20 Javascript
从数组中随机取x条不重复数据的JS代码
2013/12/24 Javascript
编写高性能Javascript代码的N条建议
2015/10/12 Javascript
JavaScript实现自动生成网页元素功能(按钮、文本等)
2015/11/21 Javascript
JS弹出对话框实现方法(三种方式)
2015/12/18 Javascript
JavaScript实现的微信二维码图片生成器的示例
2016/10/26 Javascript
Nodejs进阶:如何将图片转成datauri嵌入到网页中去实例
2016/11/21 NodeJs
JS实现复制功能
2017/03/01 Javascript
jQuery的$.extend 浅拷贝与深拷贝
2017/03/08 Javascript
JS原生带小白点轮播图实例讲解
2017/07/22 Javascript
js 概率计算(简单版)
2017/09/12 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
解决Vue 浏览器后退无法触发beforeRouteLeave的问题
2017/12/24 Javascript
详解webpack中的hash、chunkhash、contenthash区别
2018/01/05 Javascript
js正则取值的结果数组调试方法
2018/10/10 Javascript
Jquery的Ajax技术使用方法
2019/01/21 jQuery
Vue批量图片显示时遇到的路径被解析问题
2019/03/28 Javascript
使用vue完成微信公众号网页小记(推荐)
2019/04/28 Javascript
elementUI 动态生成几行几列的方法示例
2019/07/11 Javascript
JavaScript封装单向链表的示例代码
2020/09/17 Javascript
Python中的面向对象编程详解(上)
2015/04/13 Python
python中sys.argv参数用法实例分析
2015/05/20 Python
浅析python的优势和不足之处
2018/11/20 Python
Python实现银行账户资金交易管理系统
2020/01/03 Python
浅谈在django中使用redirect重定向数据传输的问题
2020/03/13 Python
文明村创建实施方案
2014/03/27 职场文书
《宋庆龄故居的樟树》教学反思
2014/04/07 职场文书
工商局局长个人对照检查材料思想汇报
2014/09/23 职场文书
公司承诺书格式范文
2015/04/28 职场文书
致我们终将逝去的青春观后感
2015/06/10 职场文书
python实现双链表
2022/05/25 Python