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 相关文章推荐
9个javascript语法高亮插件 推荐
Jul 18 Javascript
jQuery jqgrid 对含特殊字符json 数据的 Java 处理方法
Jan 01 Javascript
JS代码放在head和body中的区别分析
Dec 01 Javascript
用JavaScript实现使用鼠标画线的示例代码
Aug 19 Javascript
node.js中的fs.lchown方法使用说明
Dec 16 Javascript
DOM基础教程之使用DOM控制表格
Jan 20 Javascript
javascript实现多张图片左右无缝滚动效果
Mar 22 Javascript
利用nvm管理多个版本的node.js与npm详解
Nov 02 Javascript
angular 服务的单例模式(依赖注入模式下)详解
Oct 22 Javascript
layui实现下拉框三级联动
Jul 26 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
Nov 12 Javascript
Vue请求java服务端并返回数据代码实例
Nov 28 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
PHILIPS D1835/D1875的电路分析与打理
2021/03/02 无线电
PHP程序开发范例学习之表单 获取文本框的值
2011/08/08 PHP
使用Smarty 获取当前日期时间和格式化日期时间的方法详解
2013/06/18 PHP
php递归方法实现无限分类实例代码
2014/02/28 PHP
php_pdo 预处理语句详解
2016/11/21 PHP
PHP 序列化和反序列化函数实例详解
2020/07/18 PHP
prototype 1.5 &amp; scriptaculous 1.6.1 学习笔记
2006/09/07 Javascript
在一个浏览器里呈现所有浏览器测试结果的前端测试工具的思路
2010/03/02 Javascript
JS动态获取当前时间,并写到特定的区域
2013/05/03 Javascript
js生成缩略图后上传并利用canvas重绘
2014/05/15 Javascript
JS中的eval 为什么加括号
2016/04/13 Javascript
Google 地图事件实例讲解
2016/08/06 Javascript
JS实现复制内容到剪贴板功能
2017/02/05 Javascript
JS验证不重复验证码
2017/02/10 Javascript
jQuery插件开发发送短信倒计时功能代码
2017/05/09 jQuery
浅谈React中的元素、组件、实例和节点
2018/02/27 Javascript
vue-router 前端路由之路由传值的方式详解
2019/04/30 Javascript
vue实现顶部菜单栏
2020/11/08 Javascript
介绍Python中的__future__模块
2015/04/27 Python
python使用正则表达式提取网页URL的方法
2015/05/26 Python
详解Python中的元组与逻辑运算符
2015/10/13 Python
Python标准库笔记struct模块的使用
2018/02/22 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
Selenium chrome配置代理Python版的方法
2018/11/29 Python
利用Python实现原创工具的Logo与Help
2018/12/03 Python
python3使用GUI统计代码量
2019/09/18 Python
python超时重新请求解决方案
2019/10/21 Python
Python json格式化打印实现过程解析
2020/07/21 Python
KIKO比利时官网:意大利彩妆品牌
2017/07/23 全球购物
英国现代市场:ARKET
2019/04/10 全球购物
新闻学毕业生自荐信
2013/11/15 职场文书
思想品德课教学反思
2014/02/10 职场文书
大一学生职业生涯规划
2014/03/11 职场文书
党的群众路线教育实践活动个人对照检查材料范文
2014/09/25 职场文书
Go 语言中 20 个占位符的整理
2021/10/16 Golang
MySQL创建管理RANGE分区
2022/04/13 MySQL