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 相关文章推荐
js弹出div并显示遮罩层
Feb 12 Javascript
jQuery中width()方法用法实例
Dec 24 Javascript
使用Node.js实现HTTP 206内容分片的教程
Jun 23 Javascript
JS实现简单的二维矩阵乘积运算
Jan 26 Javascript
探讨JavaScript语句的执行过程
Jan 28 Javascript
JS轮播图中缓动函数的封装
Nov 25 Javascript
Bootstrap组合上、下拉框简单实现代码
Mar 06 Javascript
JavaScript基于activexobject连接远程数据库SQL Server 2014的方法
Jul 12 Javascript
微信小程序实现YDUI的ScrollNav组件
Feb 02 Javascript
jQuery实现动态显示select下拉列表数据的方法
Feb 05 jQuery
微信小程序实现同一页面取值的方法分析
Apr 30 Javascript
微信小程序页面渲染实现方法
Nov 06 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 数组遍历的差异(array_diff 的实现)
2008/03/23 PHP
探讨PHP中this,self,parent的区别详解
2013/06/08 PHP
php查找字符串出现次数的方法
2014/12/01 PHP
Laravel 5框架学习之Eloquent 关系
2015/04/09 PHP
IE/FireFox具备兼容性的拖动代码
2007/08/13 Javascript
JavaScript 函数调用规则
2009/09/14 Javascript
IE和firefox浏览器的event事件兼容性汇总
2009/12/06 Javascript
js控制div及网页相关属性的代码
2009/12/19 Javascript
jQuery学习之prop和attr的区别示例介绍
2013/11/15 Javascript
javascript实现动态加载CSS
2015/01/26 Javascript
javascript原生ajax写法分享
2016/04/10 Javascript
JavaScript中日常收集常见的10种错误(推荐)
2017/01/08 Javascript
使用JavaScript触发过渡效果的方法
2017/01/19 Javascript
解决vue-cli项目开发运行时内存暴涨卡死电脑问题
2019/10/29 Javascript
JavaScript实现移动端弹窗后禁止滚动
2020/05/25 Javascript
[48:48]VGJ.T vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
简单实现python收发邮件功能
2018/01/05 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
2019/01/08 Python
Python基于mysql实现学生管理系统
2019/02/21 Python
NumPy 数组使用大全
2019/04/25 Python
Python3 集合set入门基础
2020/02/10 Python
keras的ImageDataGenerator和flow()的用法说明
2020/07/03 Python
Python基于unittest实现测试用例执行
2020/11/25 Python
比利时香水网上商店:NOTINO
2018/03/28 全球购物
Under Armour安德玛荷兰官网:美国高端运动科技品牌
2019/07/10 全球购物
俄罗斯披萨、寿司和面食送货到家服务:2 Берега
2019/12/15 全球购物
公司成立感言
2014/01/11 职场文书
文明教师事迹材料
2014/01/16 职场文书
旅游管理毕业生自荐信范文
2014/03/19 职场文书
医疗专业毕业生求职信
2014/08/28 职场文书
2014年连锁店圣诞节活动方案
2014/12/09 职场文书
舞出我人生观后感
2015/06/16 职场文书
趣味运动会通讯稿
2015/07/18 职场文书
婚礼答谢词范文
2015/09/29 职场文书
golang 接口嵌套实现复用的操作
2021/04/29 Golang
python 开心网和豆瓣日记爬取的小爬虫
2021/05/29 Python