[JavaScript] localStorageを使いたい

2015/04/21

こんにちは。きんくまです。

ブラウザにデータを保存するのにいろんな方法があると思います。

cookieで保存しようかなと思ったのですが、容量が4K程度とのことでした。

>> What is the maximum size of a web browser’s cookie’s key?

ちょっとやりたいことには足りなそうなので、調べたところ、localStorageが良さそうなので、これを使うことにしました。
>> Using the Web Storage API

localStorageはcookieより容量が多くても大丈夫で、期限もつけなくて大丈夫でした。

あとIE8から対応しています。
>> localStorage – Can I use

それで使い方もとても簡単で、メソッド数も5、プロパティ数も1となっています。
>> Storage

ただ、このまま使うとデータ量が多くなってきたときに、管理がちょっと大変そうです。
というのは、localStorageは階層構造が特にないからです。なので、自分でkey部分を使うなどして階層構造を持たせる必要があります。

あと、保存できる値は文字列のみなので、数値やboolを保存したときは取り出すときにひと手間かける必要があります。

なので、まとめるクラスを作ってみました。

TypeScriptファイル

module kk {
    export class LocalStorageWrapper {
        private _name:string;
        private _localStorage:Storage;

        static available():boolean{
            return ('localStorage' in window);
        }

        constructor(name:string){
            this._name = name;
            this._localStorage = this.getLocalStorage();
            if(!this._localStorage){
                //console.log('local storage not work');
                return;
            }
        }

        findRecordIds():string[]{
            var recordIds = [];
            var keyName:string;
            var regExp:RegExp = new RegExp('^' + this._name + '-');
            for(var i = 0, len = this._localStorage.length; i < len; i++){
                keyName = this._localStorage.key(i);
                if(regExp.test(keyName)){
                    recordIds.push(keyName);
                }
            }
            return recordIds;
        }

        setString(key:string, text:string){
            if((typeof text).toLowerCase() != "string"){
                throw new Error(text + ' is not string');
            }
            this._localStorage.setItem(this.getItemId(key), text);
        }

        getString(key:string):string{
            return this._localStorage.getItem(this.getItemId(key));
        }

        setNumber(key:string, value:number){
            if((typeof value).toLowerCase() != 'number'){
                throw new Error(value + ' is not number');
            }
            this._localStorage.setItem(this.getItemId(key), value.toString());
        }

        getInt(key:string):number{
            var value = this._localStorage.getItem(this.getItemId(key));
            if(!value){
                return null;
            }
            return parseInt(value, 10);
        }

        getFloat(key:string):number{
            var value = this._localStorage.getItem(this.getItemId(key));
            if(!value){
                return null;
            }
            return parseFloat(value);
        }

        setBoolean(key:string, value:boolean){
            if((typeof value).toLowerCase() != 'boolean'){
                throw new Error(value + ' is not boolean');
            }
            this._localStorage.setItem(this.getItemId(key), value ? "t" : "f");
        }

        getBoolean(key:string):boolean{
            var value = this._localStorage.getItem(this.getItemId(key));
            if(!value){
                return null;
            }
            return value == "t";
        }

        getItemId(key:string):string{
            return this._name + '-' + key;
        }

        removeItem(key:string){
            this._localStorage.removeItem(this.getItemId(key));
        }

        clear(){
            var ids = this.findRecordIds();
            for(var i = 0, len = ids.length; i < len; i++){
                this._localStorage.removeItem(ids[i]);
            }
        }

        clearAll(){
            this._localStorage.clear();
        }

        getLocalStorage():Storage{
            return window.localStorage;
        }
    }
}

idとりまとめるところはBackbone.localStorageを参考にしました。

>> jeromegn/Backbone.localStorage

コンパイル後

var kk;
(function (kk) {
    var LocalStorageWrapper = (function () {
        function LocalStorageWrapper(name) {
            this._name = name;
            this._localStorage = this.getLocalStorage();
            if (!this._localStorage) {
                return;
            }
        }
        LocalStorageWrapper.available = function () {
            return ('localStorage' in window);
        };
        LocalStorageWrapper.prototype.findRecordIds = function () {
            var recordIds = [];
            var keyName;
            var regExp = new RegExp('^' + this._name + '-');
            for (var i = 0, len = this._localStorage.length; i < len; i++) {
                keyName = this._localStorage.key(i);
                if (regExp.test(keyName)) {
                    recordIds.push(keyName);
                }
            }
            return recordIds;
        };
        LocalStorageWrapper.prototype.setString = function (key, text) {
            if ((typeof text).toLowerCase() != "string") {
                throw new Error(text + ' is not string');
            }
            this._localStorage.setItem(this.getItemId(key), text);
        };
        LocalStorageWrapper.prototype.getString = function (key) {
            return this._localStorage.getItem(this.getItemId(key));
        };
        LocalStorageWrapper.prototype.setNumber = function (key, value) {
            if ((typeof value).toLowerCase() != 'number') {
                throw new Error(value + ' is not number');
            }
            this._localStorage.setItem(this.getItemId(key), value.toString());
        };
        LocalStorageWrapper.prototype.getInt = function (key) {
            var value = this._localStorage.getItem(this.getItemId(key));
            if (!value) {
                return null;
            }
            return parseInt(value, 10);
        };
        LocalStorageWrapper.prototype.getFloat = function (key) {
            var value = this._localStorage.getItem(this.getItemId(key));
            if (!value) {
                return null;
            }
            return parseFloat(value);
        };
        LocalStorageWrapper.prototype.setBoolean = function (key, value) {
            if ((typeof value).toLowerCase() != 'boolean') {
                throw new Error(value + ' is not boolean');
            }
            this._localStorage.setItem(this.getItemId(key), value ? "t" : "f");
        };
        LocalStorageWrapper.prototype.getBoolean = function (key) {
            var value = this._localStorage.getItem(this.getItemId(key));
            if (!value) {
                return null;
            }
            return value == "t";
        };
        LocalStorageWrapper.prototype.getItemId = function (key) {
            return this._name + '-' + key;
        };
        LocalStorageWrapper.prototype.removeItem = function (key) {
            this._localStorage.removeItem(this.getItemId(key));
        };
        LocalStorageWrapper.prototype.clear = function () {
            var ids = this.findRecordIds();
            for (var i = 0, len = ids.length; i < len; i++) {
                this._localStorage.removeItem(ids[i]);
            }
        };
        LocalStorageWrapper.prototype.clearAll = function () {
            this._localStorage.clear();
        };
        LocalStorageWrapper.prototype.getLocalStorage = function () {
            return window.localStorage;
        };
        return LocalStorageWrapper;
    })();
    kk.LocalStorageWrapper = LocalStorageWrapper;
})(kk || (kk = {}));

使い方

//簡単な使い方
var tanakaStorage = new kk.LocalStorageWrapper('tanaka');
tanakaStorage.setString('name', 'たなか');
tanakaStorage.setNumber('age', 20);

console.log(tanakaStorage.getString('name'), tanakaStorage.getInt('age'));

//1個削除
tanakaStorage.removeItem('name');

//複数削除
tanakaStorage.clear();

//=====
//複数のオブジェクトをまとめて管理して保存したい
var person1 = {
    'name':'なかむら',
    'age':30
};

var person2 = {
    'name':'たけなか',
    'age':40
};

var personsStorage = new kk.LocalStorageWrapper('person');
//プロパティを保存したいときはJSON化する
personsStorage.setString('person1', JSON.stringify(person1));
personsStorage.setString('person2', JSON.stringify(person2));

//読み込み
var personsStorage2 = new kk.LocalStorageWrapper('person');
person1 = JSON.parse(personsStorage2.getString('person1'));
person2 = JSON.parse(personsStorage2.getString('person2'));

console.log(person1, person2);
LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

LINEスタンプ作りました!
毎日使える。とぼけたウサギ。LINEスタンプ販売中! 毎日使える。とぼけたウサギ

ページトップへ戻る