30

最新のブラウザー (Chrome、Firefox、IE 9 以降、Safari、Opera) で動作するオフライン HTML5 アプリケーションを開発しようとしています。IndexedDB は (まだ) Safari でサポートされておらず、WebSQL は非推奨であるため、localStorage を使用して、ユーザーが生成した JavaScript オブジェクトを格納し、JSON.stringify()/オブジェクトJSON.parse()を出し入れすることにしました。JSON.stringify()ただし、メソッドを処理しないことがわかりました。簡単なメソッドを持つオブジェクトの例を次に示します。

    var myObject = {};
    myObject.foo = 'bar';
    myObject.someFunction = function () {/*code in this function*/}

このオブジェクトを文字列化すると (そして後で localStorage に入れると)、保持されるのは だけでmyObject.foo、 ではありませんmyObject.someFunction()

    //put object into localStorage
    localStorage.setItem('myObject',JSON.stringify(myObject));

    //pull it out of localStorage and set it to myObject
    myObject = localStorage.getItem('myObject');

    //undefined!
    myObject.someFunction

多くの人は、おそらくこの制限/機能/あなたがそれを何と呼びたいかをすでに知っていると確信しています. 私が思いついた回避策は、methods( myObject = new objectConstructor()) を使用してオブジェクトを作成し、オブジェクトのプロパティを localStorage から取り出して、作成した新しいオブジェクトに割り当てることです。これは回り道だと思いますが、私は JavaScript の世界に慣れていないので、このように解決しました。ここに私の大きな質問があります。オブジェクト全体 (プロパティ + メソッド) を localStorage に含めたいのですが。どうすればいいですか?より良いアルゴリズムや、私が知らない別の JSON メソッドを教えていただければ幸いです。

4

3 に答える 3

48

JavaScript の関数は単なるコードではありません。範囲もあります。コードは文字列化できますが、スコープはできません。

JSON.stringify()JSON がサポートする値をエンコードします。オブジェクト、配列、文​​字列、数値、およびブール値の値を持つオブジェクト。それ以外は無視されるか、エラーがスローされます。関数は、JSON でサポートされているエンティティではありません。JSON は純粋なデータのみを処理します。関数はデータではなく、より複雑なセマンティクスを持つ動作です。


つまり、JSON.stringify()仕組みを変更できるということです。2 番目の引数はreplacer関数です。したがって、関数のストリンジ化を強制することで、必要な動作を強制できます。

var obj = {
  foo: function() {
    return "I'm a function!";
  }
};

var json = JSON.stringify(obj, function(key, value) {
  if (typeof value === 'function') {
    return value.toString();
  } else {
    return value;
  }
});

console.log(json);
// {"foo":"function () { return \"I'm a function!\" }"}

しかし、JSONは functions をサポートしていないため、それを読み返すときは、関数文字列を評価し、結果をオブジェクトに戻す必要があります。


全体として、JSON のエンコーディング関数は非常に複雑になる可能性があります。これを実行してもよろしいですか?もっと良い方法がありそうです...

おそらく、代わりに生データを保存し、それをページにロードされた JS からコンストラクターに渡すことができます。localStorageデータを保持するだけですが、ページにロードされたコードはそのデータを操作するメソッドを提供します。

// contrived example...

var MyClass = function(data) {
  this.firstName = data.firstName;
  this.lastName = data.lastName;
}

MyClass.prototype.getName() {
  return this.firstName + ' ' + this.lastName;
}

localStorage.peopleData = [{
  firstName: 'Bob',
  lastName:  'McDudeFace'
}];

var peopleData = localStorage.peopleData;

var bob = new MyClass(peopleData[0]);
bob.getName() // 'Bob McDudeFace'

getName()メソッドをに保存する必要はありませんlocalStorage。そのメソッドを提供するコンストラクターにそのデータをフィードするだけです。

于 2013-08-06T19:48:02.983 に答える