1

JavaScript を多用するアプリに取り組んでいます。オブジェクト指向の実践を取り入れようとしています。この試みでは、次のような基本的なクラスを作成しました。

function Item() { this.init(); }
Item.prototype = {
  init: function () {
    this.data = {
      id: 0,
      name: "",
      description: ""     
    }
  },

  save: function() {
    alert("Saving...");
    $.ajax({
      url: getUrl(),
      type: "POST",
      data: JSON.stringify(this.data),
      contentType: "application/json"
    });
  }
}

アプリで Item インスタンスを作成し、次のようにローカル ストレージに保存しています。

Item item = new Item();
window.localStorage.setItem("itemKey", JSON.stringify(item));

別のページで、または別の時点で、次のようにローカル ストレージからそのアイテムを取得しています。

var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();

残念ながら、「保存」機能には到達していないようです。コンソール ウィンドウに、次のようなエラーが表示されます。

*save_Click (無名関数) onclick*

「(匿名関数)」は、「item.save()を呼び出していますが、アイテムは匿名型であるため、匿名関数にアクセスしようとしています」というコンソールウィンドウの言い方であるという予感があります。私の問題は、「var item」を Item クラスのインスタンスに再度変換する方法がわからないことです。誰か見せてくれませんか?

4

5 に答える 5

3

短い答え:

関数をJSONにシリアル化することはできません。

説明:

JSONは、JSリテラル構文のサブセットに基づくクロスプラットフォームのシリアル化スキームです。この場合、特定のものしか保存できません。http://www.json.org/ごと:

  • オブジェクト:オブジェクトは、名前と値のペアの順序付けられていないセットです。オブジェクトは{(左中括弧)で始まり、}(右中括弧)で終わります。各名前の後には:(コロン)が続き、名前と値のペアは、(コンマ)で区切られます。
  • 配列:配列は、順序付けられた値のコレクションです。配列は[(左角かっこ)で始まり、](右角かっこ)で終わります。値は、(コンマ)で区切られます。
  • 値:値は、二重引用符で囲まれた文字列、数値、trueまたはfalseまたはnull、またはオブジェクトまたは配列にすることができます。これらの構造はネストできます。

別の非JSプラットフォームではシリアル化を解除して使用できないため、関数をJSONにシリアル化することはできません。逆の例を考えてみましょう。サーバーにプロパティとメソッドを含むPHPオブジェクトがあるとします。そのオブジェクトをPHPでシリアル化しjson_encode()、メソッドが出力に含まれている場合、JavaScriptは、これらのメソッドを使用するどころか、メソッド内のPHPコードをどのように解析および理解できるでしょうか。

結果のJSONに表示されるのは、toString()使用しているプラ​​ットフォーム上の関数の値です。JSONセリライザーは、JSONに適さtoString()ないシリアル化されているものをすべて呼び出します。

あなたの解決策は、JSON/ローカルストレージへのインスタンスの保存を停止することだと思います。むしろ、必要なときに新しいインスタンスに戻したイン​​スタンスに関連するデータを保存します。

于 2012-04-27T12:45:43.883 に答える
2

この質問はすでに回答されていることは知っていますが、偶然これに出くわしたので、誰かが興味を持っている場合は、この問題の解決策を共有したいと思いました.

これを行う代わりに:

var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();

次のようにします。

// get serialized JSON
var itemData = window.localStorage.getItem("itemKey");
//instantiate new Item object
var item = new Item();
// extend item with data
$.extend(item, JSON.parse(itemData));

// this should now work
item.save();

これは、呼び出したい関数(つまり、save())がプロトタイプであり、インスタンスメソッドではない限り機能します(多くの場合、OPの元の質問の場合です。

$.extendメソッドはjqueryのユーティリティメソッドですが、自作するのは簡単です。

于 2013-03-12T23:17:33.010 に答える
0

プレーンなオブジェクトのみを DOMstorages (Cookie、urlparams...、JSON.stringify/による [de]serialisation を必要とするすべて) に格納できますJSON.parse。では、ajaxデータを送信するときに何をしたか

ajaxsend(this.data);

文字列のシリアル化にも適用されます。インスタンス属性 (プロトタイプ、コンストラクターなど) ではなく、データのみを保存できます。だから使う

savestring(JSON.stringify(item.data));

これはitem.data、単純なオブジェクトであるために可能です。そしてそれを復元すると、そのプレーンデータオブジェクトのみが返されます。Itemあなたの場合、 Item はパブリックに利用可能なプロパティに値 (のみ) を保持するため、プレーンデータからインスタンスを再構築するのは簡単です:

var item = new Item;
item.data = JSON.parse(getjsonstring());
于 2012-04-27T12:46:55.480 に答える
0

あなたはそれをすることはできません.javascriptはアイテムに保存機能があることをどうやって知ることができますか? json は関数をデータとして許可しません。json spec を読むだけで、関数を保存できません。

あなたがする必要があるのは、ストックしたいハッシュにシリアライズとデシリアライズのメソッドを作成することです。これにより、何をエクスポートするか、および対応する json 文字列を解析した後にオブジェクトを「起動」する方法が指定されます。

于 2012-04-27T12:47:07.573 に答える
0

免責事項

フルタイムの JS 開発者ではないため、回答にはいくつかの小さなバグがある可能性があります。

長いボーリングの説明

@JAAulde が述べたように、オブジェクトを JSON にシリアル化することはできません。これは、関数があり、使用している手法では許可されていないためです。

多くの人は、アプリケーションで使用されるオブジェクトが、ストレージから保存または復元されたものとまったく同じではない可能性があることを忘れたり無視したりします。

短くて簡単な回答

オブジェクトのデータ メンバーを単一のフィールドに既にカプセル化しているため、次のようなことを試してみてください。

// create J.S. object from prototype
Item item = new Item();

// assign values as you app. logic requires
item.data.name = "John Doe";
item.data.description = "Cool developer, office ladies, love him";

// encoded item into a JSON style string, not stored yet
var encodedItem = JSON.stringify(item.data)

// store string as a JSON string
window.localStorage.setItem("itemKey", encodedItem);

// do several stuff

// recover item from storage as JSON encoded string
var encodedItem = window.localStorage.getItem("itemKey");

// transform into J.S. object
item.data = JSON.parse(encodedItem);

// do other stuff

乾杯。

于 2012-04-27T17:11:54.237 に答える