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 delete操作符应用实例
Jan 13 Javascript
为什么要在引入的css或者js文件后面加参数的详细讲解
May 03 Javascript
jQuery lazyLoad图片延迟加载插件的优化改造方法分享
Aug 13 Javascript
没有document.getElementByName方法
Aug 19 Javascript
浅谈JavaScript的事件
Feb 27 Javascript
JavaScript简单表格编辑功能实现方法
Apr 16 Javascript
javascript操作ul中li的方法
May 14 Javascript
SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
Dec 10 Javascript
Vue+axios 实现http拦截及路由拦截实例
Apr 25 Javascript
jQuery实现锚点向下平滑滚动特效示例
Aug 29 jQuery
vue自定义标签和单页面多路由的实现代码
May 03 Javascript
vue基于better-scroll仿京东分类列表
Jun 30 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
PHP之短标签开启设置
2013/06/17 PHP
JQuery实现自定义对话框的代码
2008/06/15 Javascript
JS仿flash上传头像效果实现代码
2011/07/18 Javascript
namespace.js Javascript的命名空间库
2011/10/11 Javascript
stream.js 一个很小、完全独立的Javascript类库
2011/10/28 Javascript
基于jQuery的图片左右无缝滚动插件
2012/05/23 Javascript
JS对img标签进行优化使用onerror显示默认图像
2014/04/24 Javascript
使用JavaScript和C#中获得referer
2014/11/14 Javascript
Javascript中3个需要注意的运算符
2015/04/02 Javascript
JavaScript对数组进行随机重排的方法
2015/07/22 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
JavaScript操作XML/HTML比较常用的对象属性集锦
2015/10/30 Javascript
使用jQuery调用XML实现无刷新即时聊天
2016/08/07 Javascript
JS动态添加选项案例分析
2016/10/17 Javascript
JavaScript箭头(arrow)函数详解
2017/06/04 Javascript
JS中使用media实现响应式布局
2017/08/04 Javascript
Javascript刷新页面的实例
2017/09/23 Javascript
react 父子组件之间通讯props
2018/09/08 Javascript
如何让node运行es6模块文件及其原理详解
2018/12/11 Javascript
原生JS与JQ获取元素的区别详解
2020/02/13 Javascript
探寻python多线程ctrl+c退出问题解决方案
2014/10/23 Python
python如何创建TCP服务端和客户端
2018/08/26 Python
在django admin中添加自定义视图的例子
2019/07/26 Python
PyCharm更改字体和界面样式的方法步骤
2019/09/27 Python
python统计字符串中字母出现次数代码实例
2020/03/02 Python
python计算auc的方法
2020/09/09 Python
Python爬虫scrapy框架Cookie池(微博Cookie池)的使用
2021/01/13 Python
Python爬虫入门教程02之笔趣阁小说爬取
2021/01/24 Python
澳大利亚第一的设计师礼服租赁网站:GlamCorner
2017/08/13 全球购物
会计实习生工作总结的自我评价
2013/10/07 职场文书
高中课程设置方案
2014/05/28 职场文书
2016幼儿园新学期寄语
2015/12/03 职场文书
2016抗战胜利71周年红领巾广播稿
2015/12/18 职场文书
学生安全责任协议书
2016/03/22 职场文书
同学联谊会邀请函
2019/06/24 职场文书
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android