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 相关文章推荐
网站页面自动跳转实现方法PHP、JSP(上)
Aug 01 Javascript
用jquery方法操作radio使其默认选项是否
Sep 10 Javascript
二叉树的非递归后序遍历算法实例详解
Feb 07 Javascript
js父窗口关闭时子窗口随之关闭完美解决方案
Apr 29 Javascript
基于jQuery+Cookie实现的防止刷新的在线考试倒计时
Jun 19 Javascript
js限制文本框只能输入中文的方法
Aug 11 Javascript
jQuery插件版本冲突的处理方法分析
Jan 16 Javascript
vue2.0使用swiper组件实现轮播效果
Nov 27 Javascript
Vue中div contenteditable 的光标定位方法
Aug 25 Javascript
前端天气插件tpwidget使用方法详解
Jun 24 Javascript
javscript 数组扁平化的实现
Feb 03 Javascript
如何利用node转发请求详解
Sep 17 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
文件上传程序的全部源码
2006/10/09 PHP
PHP 源代码压缩小工具
2009/12/22 PHP
yii中widget的用法
2014/12/03 PHP
PHP计算数组中值的和与乘积的方法(array_sum与array_product函数)
2016/04/01 PHP
PHP实现页面静态化深入讲解
2021/03/04 PHP
js获取IFRAME当前的URL的方法
2013/11/13 Javascript
js实现鼠标触发图片抖动效果的方法
2015/02/27 Javascript
探究JavaScript函数式编程的乐趣
2015/12/14 Javascript
jQuery实现简单的图片查看器
2020/09/11 Javascript
学习使用jQuery表单验证插件和日历插件
2017/02/13 Javascript
基于Vue的文字跑马灯组件(npm 组件包)
2017/05/24 Javascript
angularjs实现搜索的关键字在正文中高亮出来
2017/06/13 Javascript
js判断节假日实例代码
2017/12/27 Javascript
vue.js使用v-pre与v-html输出HTML操作示例
2018/07/07 Javascript
Vue+element 解决浏览器自动填充记住的账号密码问题
2019/06/11 Javascript
vue实现后台管理权限系统及顶栏三级菜单显示功能
2019/06/19 Javascript
微信小程序的开发范式BeautyWe.js入门详解
2019/07/10 Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
2020/07/12 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
python调用机器喇叭发出蜂鸣声(Beep)的方法
2015/03/23 Python
用Python制作简单的朴素基数估计器的教程
2015/04/01 Python
python复制文件的方法实例详解
2015/05/22 Python
Python遍历文件夹 处理json文件的方法
2019/01/22 Python
python读取图片任意范围区域
2019/01/23 Python
Windows下Anaconda安装、换源与更新的方法
2020/04/17 Python
如何向scrapy中的spider传递参数的几种方法
2020/11/18 Python
英国马匹装备和马术用品购物网站:Equine Superstore
2019/03/03 全球购物
火山咖啡:Volcanica Coffee
2019/10/29 全球购物
大学自我鉴定范文
2013/12/26 职场文书
不假外出检讨书
2014/01/27 职场文书
捐书活动总结
2014/05/04 职场文书
社区戒毒工作方案
2014/06/04 职场文书
公司行政管理制度范本
2015/08/05 职场文书
青年志愿者活动感想
2015/08/07 职场文书
logback如何自定义日志存储
2021/08/30 Java/Android
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫