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.stringify
和JSON.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()