反序列化JavaScript对象实例
我正在开发一款大量使用JavaScript的应用程序。我试图包括一些面向对象的实践。在这次尝试中,我创建了一个基本类,如下所示:反序列化JavaScript对象实例,javascript,oop,Javascript,Oop,我正在开发一款大量使用JavaScript的应用程序。我试图包括一些面向对象的实践。在这次尝试中,我创建了一个基本类,如下所示: function Item() { this.init(); } Item.prototype = { init: function () { this.data = { id: 0, name: "", description: "" } }, save: function() {
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 = new Item();
window.localStorage.setItem("itemKey", JSON.stringify(item));
var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();
在另一个页面上,或在另一个时间,我正在从本地存储中检索该项,如下所示:
Item item = new Item();
window.localStorage.setItem("itemKey", JSON.stringify(item));
var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();
不幸的是,save函数似乎没有达到。在console窗口中,有一个错误显示:
*单击“保存”
匿名函数
onclick*
我有一种预感,匿名函数是控制台窗口调用item.save的方式,但item是匿名类型,所以我尝试访问匿名函数。我的问题是,我不确定如何将var item再次转换为item类实例。有人能给我看看吗?简短回答:
无法将函数序列化为JSON
说明:
JSON是一种基于JS文本语法子集的跨平台序列化方案。在这种情况下,它只能存储某些东西。Per:
对象:对象是一组无序的名称/值对。对象以{左大括号开始,以}右大括号结束。每个名称后面跟着:冒号,名称/值对之间用逗号分隔。
数组:数组是值的有序集合。数组以[左括号]开始,以[右括号]结束。值之间用逗号分隔。
值:值可以是双引号中的字符串、数字、true或false或null、对象或数组。这些结构可以嵌套。
函数无法序列化为JSON,因为另一个非JS平台将无法取消序列化并使用它。反过来考虑这个例子。假设我的服务器上有一个PHP对象,其中包含属性和方法。如果我用PHP的json_编码序列化该对象,并且输出中包含方法,那么我的JavaScript如何能够解析和理解方法中的PHP代码,更不用说使用这些方法了
您在生成的JSON中看到的是您正在使用的平台上函数的toString值。JSON序列化程序对任何不适合JSON的被序列化对象调用toString
我相信您的解决方案是停止在JSON/本地存储中存储实例。相反,请保存实例的相关数据,并在需要时将其设置回新实例。简短回答:
无法将函数序列化为JSON
说明:
JSON是一种基于JS文本语法子集的跨平台序列化方案。在这种情况下,它只能存储某些东西。Per:
对象:对象是一组无序的名称/值对。对象以{左大括号开始,以}右大括号结束。每个名称后面跟着:冒号,名称/值对之间用逗号分隔。
数组:数组是值的有序集合。数组以[左括号]开始,以[右括号]结束。值之间用逗号分隔。
值:值可以是双引号中的字符串、数字、true或false或null、对象或数组。这些结构可以嵌套。
函数无法序列化为JSON,因为另一个非JS平台将无法取消序列化并使用它。反过来考虑这个例子。假设我的服务器上有一个PHP对象,其中包含属性和方法。如果我用PHP的json_编码序列化该对象,并且输出中包含方法,那么我的JavaScript如何能够解析和理解方法中的PHP代码,更不用说使用这些方法了
您在生成的JSON中看到的是您正在使用的平台上函数的toString值。JSON序列化程序对任何不适合JSON的被序列化对象调用toString
我相信您的解决方案是停止在JSON/本地存储中存储实例。相反,保存实例的相关数据,在需要时将其设置回新实例。您只能将普通对象存储在DOMstorages cookies、urlparams…,所有需要通过JSON.stringify/JSON.parse进行[反]序列化的内容中。那么您在发送ajax数据时做了什么
ajaxsend(this.data);
也适用于字符串序列化。您只能存储数据,不能存储prototype、constructor等实例属性。。所以使用
savestring(JSON.stringify(item.data));
这是可能的,因为item.data是一个简单的对象。当恢复它时,您将只返回该普通数据对象。在您的情况下,很容易从普通数据重建项实例,因为您的项仅在公共可用属性中保留其值:
var item = new Item;
item.data = JSON.parse(getjsonstring());
您只能将普通对象存储在DOMstorages cookies、urlparams…,以及需要通过JSON.stringify/JSON.parse进行[de]序列化的所有内容中。那么您在发送ajax数据时做了什么
ajaxsend(this.data);
也适用于字符串序列化。您只能存储数据,不能存储prototype、constructor等实例属性。。所以
使用
这是可能的,因为item.data是一个简单的对象。当恢复它时,您将只返回该普通数据对象。在您的情况下,很容易从普通数据重建项实例,因为您的项仅在公共可用属性中保留其值:
var item = new Item;
item.data = JSON.parse(getjsonstring());
您不能这样做,javascript怎么可能知道该项具有保存功能?json不允许函数作为数据。只要阅读json规范,就无法保存函数
您需要做的是在要存储的哈希中创建一个序列化和反序列化方法。这将指定要导出的内容以及在解析相应的json字符串后如何唤醒对象。如果不能这样做,javascript怎么可能知道该项具有保存功能?json不允许函数作为数据。只要阅读json规范,就无法保存函数 您需要做的是在要存储的哈希中创建一个序列化和反序列化方法。这将指定要导出的内容以及在解析相应的json字符串后如何唤醒对象。免责声明 不是全职的J.S.开发者,answer可能有一些小错误: 冗长乏味的解释 正如@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
// 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();
干杯。免责声明
不是全职的J.S.开发者,answer可能有一些小错误:
冗长乏味的解释
正如@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
// 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();
干杯。我知道这个问题已经得到了回答,但是我无意中发现了这个问题,如果有人感兴趣,我想分享这个问题的解决方案 而不是这样做:
var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();
这样做:
// 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
// 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();
只要你想调用ie,save的函数是原型,而不是一个实例方法,它就可以正常工作。通常情况下,OP的原始问题就是这样
$.extend方法是jquery的一种实用方法,但是您自己的方法并不重要。我知道这个问题已经得到了回答,但是我无意中发现了这个问题,如果有人感兴趣的话,我想分享这个问题的解决方案 而不是这样做:
var item = window.localStorage.getItem("itemKey");
item = JSON.parse(item);
item.save();
这样做:
// 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
// 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();
只要你想调用ie,save的函数是原型,而不是一个实例方法,它就可以正常工作。通常情况下,OP的原始问题就是这样
$.extend方法是jquery的一种实用方法,但是你自己使用它是很简单的。有什么特别的原因来尝试模仿经典模式而不仅仅是使用原型模式吗?我不知道原型模式是什么。是的,我的错。我实际上是想说原型继承成语。什么是原型继承成语?你有链接吗?我在谷歌上搜索的时候运气不好。有没有什么特别的理由来模仿经典模式而不仅仅是使用原型模式?我不知道原型模式是什么。是的,我的错。我实际上是想说原型继承成语。什么是原型继承成语?你有链接吗?我在谷歌上搜索了它,但运气不好。OP不存储实例,也没有任何函数。他只想知道如何从他的数据中重新实例化一个项目。@Bergi一点也不正确。她明确表示她有一个带有方法的对象实例,尝试JSON序列化然后取消序列化,并且在取消序列化的一侧丢失了方法。我提出的解决方案可能无法完全解决如何序列化JS对象W/方法,但我清楚地说明了她的方法有什么问题,并提出了我认为是一个更好的方法去做它。我看过ajax函数,OP不存储实例,也没有函数。他只想知道如何从他的数据中重新实例化一个项目。@Bergi一点也不正确。她明确表示她有一个带有方法的对象实例,尝试JSON序列化然后取消序列化,并且在取消序列化的一侧丢失了方法。我提出的解决方案可能无法完全解决如何用方法序列化JS对象的问题,但我清楚地说明了她的方法的错误,并建议
我认为这是一个更好的方法。我明白了。我已经看过ajax函数了。