灵魂五问localStorage存储的键值采用什么字符编码5M的单位是什么localStorage键占不占存储空间localStorage的键的数量,对写和读性能的影响写个方法统计一个localStorage已使用空间 我们挨个解答,之后给各位面试官又多了一个面试题。 我们常说localStorage存储空间是5M,请问这个5M的单位是什么?localStorage存储的键值采用什么字符编码? 打开相对权威的MDNlocalStoragedescription〔1〕 ThekeysandthevaluesstoredwithlocalStoragearealwaysintheUTF16DOMString〔2〕format,whichusestwobytespercharacter。Aswithobjects,integerkeysareautomaticallyconvertedtostrings。 翻译成中文: localStorage存储的键和值始终采用UTF16DOMString格式,每个字符使用两个字节。与对象一样,整数键将自动转换为字符串。 答案:UTF16 MDN这里描述的没有问题,也有问题,因为UTF16,每个字符使用两个字节,是有前提条件的,就是码点小于0xFFFF(65535),大于这个码点的是四个字节。 这是全文的关键。5M的单位是什么 5M的单位是什么? 选项:字符的个数字节数字符的长度值bit数utf16编码单元 以前不知道,现代浏览器,准确的应该是选项3,字符的长度,亦或选项5,utf16编码单元 字符的个数,并不等于字符的长度,这一点要知道:a。length1人。length1。length2。length2 现代浏览器对字符串的处理是基于UTF16DOMString〔2〕。 但是说5M字符串的长度,显然有那么点怪异。 而根据UTF16编码规则,要么2个字节,要么四个字节,所以不如说是10M的字节数,更为合理。 当然,2个字节作为一个utf16的字符编码单元,也可以说是5M的utf16的编码单元。 我们先编写一个utf16字符串计算字节数的方法:非常简单,判断码点决定是2还是4functionsizeofUtf16Bytes(str){vartotal0,charCode,i,for(i0,lenstr。i){charCodestr。charCodeAt(i);if(charCode0xffff){total2;}else{total4;}}} 我们再根绝10M的字节数来存储 我们留下8个字节数作为key,8个字节可是普通的4个字符换,也可是码点大于65535的3个字符,也可是是组合。 下面的三个组合,都是可以的,aaaaaa 在此基础上增加任意一个字符,都会报错异常异常。constcharTxt人;letcount(10102410242)82;letcontentnewArray(count)。fill(charTxt)。join();localStorage。clear();try{localStorage。setItem(key,content);}catch(err){console。log(err,err);}constsizeKeysizeofUtf16Bytes(key);constcontentSizesizeofUtf16Bytes(content);console。log(keysize:,sizeKey,content。length);console。log(contentsize:,contentSize,content。length);console。log(totalsize:,sizeKeycontentSize,content。lengthkey。length); 现代浏览器的情况下: 所以,说是10M的字节数,更为准确,也更容易让人理解。 如果说5M,那其单位就是字符串的长度,而不是字符数。 答案:字符串的长度值,或者utf16的编码单元 更合理的答案是10M字节空间。localStorage键占不占存储空间 我们把key和val各自设置长2。5M的长度constcharTletcount(2。510241024);letcontentnewArray(count)。fill(charTxt)。join();constkeynewArray(count)。fill(charTxt)。join();localStorage。clear();try{console。time(setItem)localStorage。setItem(key,content);console。timeEnd(setItem)}catch(err){console。log(errcode:,err。code);console。log(errmessage:,err。message)} 执行正常。 我们把content的长度加1,变为2。5M1,key的长度依旧是2。5M的长度constcharTletcount(2。510241024);letcontentnewArray(count)。fill(charTxt)。join()1;constkeynewArray(count)。fill(charTxt)。join();localStorage。clear();try{console。time(setItem)localStorage。setItem(key,content);console。timeEnd(setItem)}catch(err){console。log(errcode:,err。code);console。log(errmessage:,err。message)} 产生异常,存储失败。至于更多异常详情吗,参见localstorage功能检测〔3〕:functionstorageAvailable(type){try{storagewindow〔type〕;storage。setItem(x,x);storage。removeItem(x);}catch(e){returneinstanceofDOMException(everythingexceptFirefoxe。code22Firefoxe。code1014testnamefieldtoo,becausecodemightnotbepresenteverythingexceptFirefoxe。nameQuotaExceededErrorFirefoxe。nameNSERRORDOMQUOTAREACHED)acknowledgeQuotaExceededErroronlyiftheressomethingalreadystored(storagestorage。length!0);}} 答案:占空间键的数量,对读写的影响 我们5001000键,如下letkeyCount5001000;localStorage。clear();for(leti0;ikeyCi){localStorage。setItem(i,);}setTimeout((){console。time(savecost);localStorage。setItem(a,1);console。timeEnd(savecost);},2000)setTimeout((){console。time(readcost);localStorage。getItem(a);console。timeEnd(readcost);},2000)savecost:0。05615234375msreadcost:0。008056640625ms 你单独执行保存代码:localStorage。clear();console。time(savecost);localStorage。setItem(a,1);console。timeEnd(savecost);savecost:0。033203125ms 可以多次测试,影响肯定是有的,也仅仅是数倍,不是特别的大。 反过来,如果是保存的值表较大呢?constcharTconstcount5102410241constval1newArray(count)。fill(charTxt)。join();setTimeout((){localStorage。clear();console。time(savecost1);localStorage。setItem(a,val1);console。timeEnd(savecost1);},1000)setTimeout((){localStorage。clear();console。time(savecost2);localStorage。setItem(a,a);console。timeEnd(savecost2);},1000)savecost1:12。276123046875mssavecost2:0。010009765625ms 可以多测试很多次,单次值的大小对存的性能影响非常大,读取也一样,合情合理之中。 所以尽量不要保存大的值,因为其是同步读取,纯大数据,用indexedDB就好。 答案:键的数量对读取性能有影响,但是不大。值的大小对性能影响更大,不建议保存大的数据。写个方法统计一个localStorage已使用空间 现代浏览器的精写版本:functionsieOfLS(){returnObject。entries(localStorage)。map(vv。join())。join()。} 测试代码:localStorage。clear();localStorage。setItem(,1);localStorage。setItem(,1111);console。log(size:,sieOfLS())23915291523html的协议标准 WHATWG超文本应用程序技术工作组的localstorage〔4〕协议定了localStorage的方法,属性等等,并没有明确规定其存储空间。也就导致各个浏览器的最大限制不一样。 其并不是ES的标准。页面的utf8编码 我们的html页面,经常会出现。告知浏览器此页面属于什么字符编码格式,下一步浏览器做好解码工作。headmetacharsetUTF8metahttpequivXUACompatiblecontentIEedgemetanameviewportcontentwidthdevicewidth,initialscale1。0title容器titlehead 这和localStorage的存储没有半毛钱的关系。localStorage扩容 localStorage的空间是10M的字节数,一般情况是够用,可是人总是有贪欲。真达到了空间限制,怎么弄? localStorage扩容就是一个话题。