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实现二分查找法实现代码
Nov 12 Javascript
Tinymce+jQuery.Validation使用产生的BUG
Mar 29 Javascript
JavaScript中去掉数组中的重复值的实现方法
Aug 03 Javascript
jquery操作checkbox实现全选和取消全选
May 02 Javascript
基于jQuery实现的无刷新表格分页实例
Feb 17 Javascript
浅谈js的url解析函数封装
Jun 28 Javascript
JS实现拖动滚动条评分的效果代码分享
Sep 29 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
Jan 18 Javascript
Express URL跳转(重定向)的实现方法
Apr 07 Javascript
老生常谈Bootstrap媒体对象
Jul 06 Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
Jul 11 Javascript
javascript 通过键名获取键盘的keyCode方法
Dec 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中文本数据翻页(留言本翻页)
2006/10/09 PHP
php中DOMDocument简单用法示例代码(XML创建、添加、删除、修改)
2010/12/19 PHP
PHP学习笔记之二
2011/01/17 PHP
php断点续传之文件分割合并详解
2016/12/13 PHP
php递归函数怎么用才有效
2018/02/24 PHP
javascript CSS画图之基础篇
2009/07/29 Javascript
extjs 学习笔记(三) 最基本的grid
2009/10/15 Javascript
fireworks菜单生成器mm_menu.js在 IE 7.0 显示问题的解决方法
2009/10/20 Javascript
YUI模块开发原理详解
2013/11/18 Javascript
javascript笛卡尔积算法实现方法
2015/04/08 Javascript
原生js实现的贪吃蛇网页版游戏完整实例
2015/05/18 Javascript
JS从数组中随机取出几个数组元素的方法
2016/08/02 Javascript
图片上传之FileAPI与NodeJs
2017/01/24 NodeJs
使用原生js封装的ajax实例(兼容jsonp)
2017/10/12 Javascript
极简主义法编写JavaScript类
2017/11/02 Javascript
js中apply和Math.max()函数的问题及区别介绍
2018/03/27 Javascript
vue自定义移动端touch事件之点击、滑动、长按事件
2018/07/10 Javascript
Vue 进阶之路(三)
2019/04/18 Javascript
JavaScript定时器设置、使用与倒计时案例详解
2019/07/08 Javascript
微信小程序如何实现精确的日期时间选择器
2020/01/21 Javascript
[01:05:07]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第一场2月1日
2021/03/11 DOTA
Python代码的打包与发布详解
2014/07/30 Python
python友情链接检查方法
2015/07/08 Python
Python 的类、继承和多态详解
2017/07/16 Python
Python实现的破解字符串找茬游戏算法示例
2017/09/25 Python
python、java等哪一门编程语言适合人工智能?
2017/11/13 Python
Windows下的Jupyter Notebook 安装与自定义启动(图文详解)
2018/02/21 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
python async with和async for的使用
2019/06/20 Python
python paramiko远程服务器终端操作过程解析
2019/12/14 Python
python实现从ftp服务器下载文件
2020/03/03 Python
一文轻松掌握python语言命名规范规则
2020/06/18 Python
英国打印机墨盒销售网站:Ink Factory
2019/10/07 全球购物
驾驶员培训方案
2014/05/01 职场文书
开业庆典活动策划方案
2014/09/21 职场文书
2015学校师德师风工作总结
2015/04/22 职场文书