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 相关文章推荐
如何使用jQuery Draggable和Droppable实现拖拽功能
Jul 05 Javascript
JS 获取select(多选下拉)中所选值的示例代码
Aug 02 Javascript
JavaScript中访问节点对象的方法有哪些如何使用
Sep 24 Javascript
jQuery经过一段时间自动隐藏指定元素的方法
Mar 17 Javascript
JavaScript中绑定事件的三种方式及去除绑定
Nov 05 Javascript
html中鼠标滚轮事件onmousewheel的处理方法
Nov 11 Javascript
canvas绘制的直线动画
Jan 23 Javascript
js如何获取网页所有图片
May 12 Javascript
vue中v-model动态生成的实例详解
Oct 27 Javascript
JavaScript实现三级级联特效
Nov 05 Javascript
JQuery判断radio单选框是否选中并获取值的方法
Jan 17 jQuery
vue项目引入ts步骤(小结)
Oct 31 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的大小写敏感问题整理
2011/12/29 PHP
解析关于java,php以及html的所有文件编码与乱码的处理方法汇总
2013/06/24 PHP
PHP文件下载实例代码浅析
2016/08/17 PHP
javascript 读取XML数据,在页面中展现、编辑、保存的实现
2009/10/27 Javascript
jQuery选择器中含有空格的使用示例及注意事项
2013/08/25 Javascript
在JS中解析HTML字符串示例代码
2014/04/16 Javascript
Javascript基础知识(二)事件
2014/09/29 Javascript
JavaScript不使用prototype和new实现继承机制
2014/12/29 Javascript
jQuery实现的Div窗口震动效果实例
2015/08/07 Javascript
HTML5之WebSocket入门3 -通信模型socket.io
2015/08/21 Javascript
Jquery实现简单的轮播效果(代码管用)
2016/03/14 Javascript
如何提高数据访问速度
2016/12/26 Javascript
Js自动截取字符串长度,添加省略号(……)的实现方法
2017/03/06 Javascript
jQuery is not defined 错误原因与解决方法小结
2017/03/19 Javascript
ES6新特性八:async函数用法实例详解
2017/04/21 Javascript
js实现导航跟随效果
2018/11/17 Javascript
VUE注册全局组件和局部组件过程解析
2019/10/10 Javascript
es6 for循环中let和var区别详解
2020/01/12 Javascript
python在Windows8下获取本机ip地址的方法
2015/03/14 Python
自动化Nginx服务器的反向代理的配置方法
2015/06/28 Python
python算法演练_One Rule 算法(详解)
2017/05/17 Python
Python简单定义与使用字典dict的方法示例
2017/07/25 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
python同时遍历数组的索引和值的实例
2018/11/15 Python
numpy.random.shuffle打乱顺序函数的实现
2019/09/10 Python
python GUI库图形界面开发之PyQt5日期时间控件QDateTimeEdit详细使用方法与实例
2020/02/27 Python
pandas数据选取:df[] df.loc[] df.iloc[] df.ix[] df.at[] df.iat[]
2020/04/24 Python
numpy中生成随机数的几种常用函数(小结)
2020/08/18 Python
python线程优先级队列知识点总结
2021/02/28 Python
CSS3中利用animation属性创建雪花飘落特效
2014/05/14 HTML / CSS
css3中单位px,em,rem,vh,vw,vmin,vmax的区别及浏览器支持情况
2016/12/06 HTML / CSS
欧洲最大的滑雪假期供应商之一:Sunweb Holidays
2018/01/06 全球购物
英国绿色商店:Natural Collection
2019/05/03 全球购物
荣耀俄罗斯官网:HONOR俄罗斯
2020/10/31 全球购物
小学新学期寄语
2014/04/02 职场文书
jdbc中自带MySQL 连接池实践示例
2022/07/23 MySQL