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

Posted

技术标签:

【中文标题】JSON.parse(JSON.stringify(object_with_function)) != object_with_function【英文标题】: 【发布时间】:2018-07-03 06:05:30 【问题描述】:

所以我有以下代码:

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);

它提醒未定义。

【问题讨论】:

只是为了澄清,我的警报是错误的。如果你们是真的,那可能是我的电脑坏了 即使去掉JSON.stringifyJSON.parse,条件也会返回false。函数比较见***.com/a/9817706/4636715。 两个单独的对象永远不会相等:console.log( === ) 好的,所以我有一个误导性的例子,看看这段代码:alert(JSON.parse(JSON.stringify(func: function()alert(1);)).func); 【参考方案1】:

见this question。

JSON.stringify() 将对 JSON 支持的值进行编码。对象与 可以是对象、数组、字符串、数字和布尔值的值。 其他任何内容都将被忽略或抛出错误。函数不是一个 JSON 中支持的实体。 JSON 只处理纯数据,函数是 不是数据,而是具有更复杂语义的行为。

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

【讨论】:

我想这就是我需要的。对不起,我有一个非常糟糕和误导性的例子。看看这个例子: alert(JSON.parse(JSON.stringify(func: function()alert(1);)).func);【参考方案2】:

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

【讨论】:

我认为您的意思是“对象”而不是“功能”。 你不会得到不同的功能。您根本无法从 JSON 中获取函数对象,因为 JSON 不支持函数。【参考方案3】:

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));

【讨论】:

【参考方案4】:

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

console.log( == );

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

在第一种情况下,我们正在比较 2 个新的空对象。每个对象在内存中都有自己的分配,因此在比较引用类型时,这就是比较的内容。因此,false 被返回,因为它们不一样。

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

【讨论】:

看看这个我有一个误导性的例子 alert(JSON.parse(JSON.stringify(func: function()alert(1);)).func); @JasonC。函数不能被字符串化。

以上是关于JSON.parse(JSON.stringify(object_with_function)) != object_with_function的主要内容,如果未能解决你的问题,请参考以下文章

关于JSON.stringify()与JSON.parse()

JSON.stringify()和JSON.parse()

JSON.stringify()和JSON.parse()

JSON.stringify()与JSON.parse()区别

JSON.parse()和JSON.stringify()

JSON.parse()与JSON.stringify()与qs.stringify的区别