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实现轮显新闻标题链接
Aug 13 Javascript
Javascript入门学习资料收集整理篇
Jul 06 Javascript
基于Jquery的仿照flash放大图片效果代码
Mar 16 Javascript
JavaScript异步编程:异步数据收集的具体方法
Aug 19 Javascript
JQuery EasyUI 加载两次url的原因分析及解决方案
Aug 18 Javascript
jquery+json实现动态商品内容展示的方法
Jan 14 Javascript
AngularJS入门教程之AngularJS表达式
Apr 18 Javascript
基于jQuery插件jqzoom实现的图片放大镜效果示例
Jan 23 Javascript
微信小程序简单实现form表单获取输入数据功能示例
Nov 30 Javascript
让Vue也可以使用Redux的方法
May 23 Javascript
2020京东618叠蛋糕js脚本(亲测好用)
Jun 02 Javascript
vue特效之翻牌动画
Apr 20 Vue.js
深入解析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
PHP数据库操作面向对象的优点
2006/10/09 PHP
来自PHP.NET的入门教程
2006/10/09 PHP
PHP 利用AJAX获取网页并输出的实现代码(Zjmainstay)
2012/08/31 PHP
简明json介绍
2008/09/28 Javascript
客户端限制只能上传jpg格式图片的js代码
2010/12/09 Javascript
基于jquery的blockui插件显示弹出层
2011/04/14 Javascript
js DOM 元素ID就是全局变量
2012/09/20 Javascript
jquery和ajax的关系详细介绍
2013/11/29 Javascript
nodejs之请求路由概述
2014/07/05 NodeJs
两种方法基于jQuery实现IE浏览器兼容placeholder效果
2014/10/14 Javascript
Google Maps API地图应用示例分享
2014/10/23 Javascript
在jQuery中使用$而避免跟其它库产生冲突的方法
2015/08/13 Javascript
jQuery给元素添加样式的方法详解
2015/12/30 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
2016/07/12 Javascript
Extjs让combobox写起来简洁又漂亮
2017/01/05 Javascript
js实现延迟加载的几种方法
2017/04/24 Javascript
JS实现瀑布流布局
2017/10/21 Javascript
Angular2实现的秒表及改良版示例
2019/05/10 Javascript
JS中超越现实的匿名函数用法实例分析
2019/06/21 Javascript
JS实现的tab切换并显示相应内容模块功能示例
2019/08/03 Javascript
zookeeper python接口实例详解
2018/01/18 Python
在PyCharm中三步完成PyPy解释器的配置的方法
2018/10/29 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
2020/02/17 Python
详解Python yaml模块
2020/09/23 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
统计员岗位职责
2013/11/14 职场文书
高中生学习的自我评价
2013/12/14 职场文书
《傅雷家书》教学反思
2014/04/20 职场文书
小学先进集体事迹材料
2014/05/31 职场文书
2014迎接教师节演讲稿
2014/09/10 职场文书
办公室主任四风问题对照检查材料思想汇报
2014/09/28 职场文书
个人先进事迹材料
2014/12/29 职场文书
感谢信的格式
2015/01/21 职场文书
Python 文本滚动播放器的实现代码
2021/04/25 Python
mysql事务隔离级别详情
2021/10/24 MySQL
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记