JSON.parse(JSON.stringify(object_with_function))!= object_with_function

时间:2018-07-03 06:05:30

标签: javascript

所以我有以下代码:

alert(JSON.parse(JSON.stringify({func: function(){alert(1);}})) == {func: function(){alert(1);}});

基本上,我使用JSON.parse一个JSON.stringify对象(包含一个函数),结果与原始对象不同(警报时我得到了假)

这使我陷入了游戏的保存进度功能中。

帮助表示赞赏!

编辑: 抱歉,不好的例子,请改试试:

alert(JSON.parse(JSON.stringify({func:function(){alert(1);}})))。func);

它会发出未定义的警报。

4 个答案:

答案 0 :(得分:2)

请参见this question

  

JSON.stringify()将对JSON支持的值进行编码。与对象   可以是对象,数组,字符串,数字和布尔值的值。   其他任何事情都将被忽略或引发错误。功能不是   JSON中受支持的实体。 JSON仅处理纯数据,功能是   不是数据,而是具有更复杂语义的行为。

这意味着在具有方法的对象上使用JSON.parse(JSON.stringify())将不等于尚未进行字符串化的对象。

答案 1 :(得分:1)

因为Object是引用类型,所以JSON.parse(JSON.stringify())返回一个新的Object,并且==表达式在比较引用类型时会比较它们的地址,因此它返回false。

答案 2 :(得分:1)

JSON.stringify()将对JSON支持的值进行编码。与对象 可以是对象,数组,字符串,数字和布尔值的值。 其他任何事情都将被忽略或引发错误。功能不是 JSON中受支持的实体。 JSON仅处理纯数据,功能是 不是数据,而是具有更复杂语义的行为。

因此,基本上,在对对象进行字符串化和解析时,您需要自己的reducer和解析器,可以这样完成:

var myObject = {
        num: 50,
        str: 'A string here',
        today: new Date(),
        ar: ['one', 'two', 'three'],
        myFunction: function(val) {
            console.log(val);
        }
    }

    // example replacer function
    function replacer(name, val) {
        // convert RegExp or function to string
        if ( val && val.constructor === Function) {
            return val.toString();
        } else {
            return val; // return as is
        }
    };

    // example replacer function
    function parser(name, val) {
        if ( val && typeof val == "string" && val.startsWith("function")){
            return new Function('return ' + val)();
        } else {
            return val; // return as is
        }
    };
    var jsonObject = JSON.parse(JSON.stringify(myObject, replacer), parser);

    //because of different reference , this will evaluate to false
    console.log(myObject.myFunction == jsonObject.myFunction);
    //true because of same content
    console.log(myObject.myFunction.toString() == jsonObject.myFunction.toString());
    //evaluate same as same function
    console.log(myObject.myFunction(5) == jsonObject.myFunction(5));

答案 3 :(得分:0)

我认为您的问题的答案可以证明为:

console.log({} == {});

var example = {};
var test = example;
console.log(example == test);

在第一种情况下,我们正在比较2个新的空对象。每个对象在内存中都有其自己的分配,因此在比较引用类型时,即进行比较。因此,返回false,因为它们不相同。

在第二个示例中,我们将新变量(test)指向现有对象(example)。在这里,我们看到它返回true,因为这次我们正在比较相同的内存分配。