【问题标题】:JSON.parse() breaks object functionJSON.parse() 破坏对象函数
【发布时间】:2015-08-12 14:07:41
【问题描述】:

我有对象用 JSON.stringify() 'stringify'd,然后用 localstorage.setItem() 保存,然后用 localstorage.getItem() 检索,然后用 JSON.parse() 解析,最后被返回到程序中使用的对象数组中。这是我的代码:

var exampleObjects = [];

function objectExample() {
    this.exampleFunction = function() {
            return this.otherObjectCreatedElsewhere.value;
    }
    this.otherObjectCreatedElsewhere;
}

function main() {
    exampleObjects[ 0 ] = new objectExample();
    exampleObjects[ 0 ].otherObjectCreatedElsewhere = otherObjectCreatedElsewhere;
    exampleObjects[ 0 ].exampleFunction(); //Works
    var save0 = JSON.stringify( exampleObjects[ 0 ] );
    localstorage.setItem( 'key', save0 );
    save0 = localstorage.getItem( 'key' );
    exampleObjects[ 0 ] = JSON.parse( save0 );
    exampleObjects[ 0 ].exampleFunction(); //No longer works, instead throws error exampleObjects[ 0 ].exampleFunction is not a function
}

main();

现在我已经使用 reviver 方法查找了 JSON.parse,但我终生无法弄清楚。我没有上过学,这只是我的一个爱好,但我已经培养了几年了。我真的很喜欢它,但这样的时刻令人沮丧。

编辑

我已经通过 cloudfeet 的宝贵建议解决了这个问题。基本上我从保存的 JSON 字符串中取出对象,然后将它们解析为对象,然后创建一个新对象并重新分配所有丰富的属性。

再次感谢!

【问题讨论】:

  • 函数在 JSON 语法中无效。请参阅json.org — 您可以拥有字符串、数字、对象、数组、truefalsenull,但不能拥有函数。

标签: javascript json


【解决方案1】:

JSON 不是 JavaScript。它使用 JavaScript 语法的有限子集,但它可以编码的唯一数据类型是:

  • 布尔值
  • 号码
  • 字符串
  • 对象:从字符串映射到任何类型
  • 数组:值列表

(见http://json.org/

JSON 能够序列化函数。任何函数都将被省略(如undefined),原型将被销毁等。

所以:您需要做的是从丰富的对象(使用方法等)转换为 JSON,然后能够再次转换回来。


编辑:一个粗略的例子:

function MyObj(name, age) {
    this.name = name;
    this.age = age;
    this.hello = function () {
        alert('Hello, ' + this.name + '!');
    };
}

当你序列化这个时,你会得到{"name": "Sarah", "age": 38} - 没有"hello" 条目。

所以,要解码,你需要解压:

var array = JSON.parse(savedString); // Plain JSON
for (var i = 0; i < array.length; i++) {
    var plainObj = array[i];
    var richObj = new MyObj(plainObj.name, plainObj.age); // reconstruct
    array[i] = richObj;
}

这是一种简单的方法,解码逻辑是硬编码的——有一些方法可以让它更漂亮,比如JSON.stringify()JSON.parse()的第二个参数,以及.toJSON()方法,但大致相同事物,组织方式不同。

【讨论】:

  • 啊好吧,这很有道理!但这就是复活者所做的吗?我会尝试设计一些发现无价值属性的东西,然后以这种方式重新添加方法/函数吗?例如。如果 this.prop = undefined 那么 this.prop = function(){ stuff }?你认为这样的事情会奏效吗?
  • 您最好使用new MyObj() 语法重构对象,而不是尝试添加单个方法。 reviver 是一个翻译函数——因此,它查看普通对象,决定值“应该”是什么类型并返回“真实”版本。它或多或少与我在示例中编写的代码完全相同,但包装方式不同。我个人从未使用过 reviver 函数。
  • 这太棒了——我不得不说。非常感谢您花时间为我展示这个示例。我会试试这个。从我阅读的内容来看,reviver 功能的想法对我来说有点陌生,但是您解释一切的方式很完美,我现在将尝试实现它。
  • 不幸的是,cloudfeet,我无法通过 JSON.decode() 部分。我无法从几次搜索中找到 JSON.decode()。这是将 JSON 字符串放入数组的唯一方法吗?谢谢。
  • 你是个英雄——很抱歉最后一个问题。我已经按照你所说的解决了这个问题。基本上,我从保存的 JSON 中获取对象,然后解析它们,然后创建一个新对象并重新分配所有丰富的属性。再次感谢!
猜你喜欢
  • 2022-01-23
  • 1970-01-01
  • 2018-04-02
  • 2018-03-10
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多