I have the following code:
JSON.parse(JSON.stringify({func: function(){alert(1);}})).func
I JSON.parse a JSON.stringify object (that contained a function), but the result was undefined. Why is this?
I have the following code:
JSON.parse(JSON.stringify({func: function(){alert(1);}})).func
I JSON.parse a JSON.stringify object (that contained a function), but the result was undefined. Why is this?
See this question.
JSON.stringify() will encode values that JSON supports. Objects with values that can be objects, arrays, strings, numbers and booleans. Anything else will be ignored or throw errors. Functions are not a supported entity in JSON. JSON handles pure data only, functions are not data, but behavior with more complex semantics.
This means that using JSON.parse(JSON.stringify()) on a object with methods will not be equal to the object that hasn't been stringified.
JSON.stringify() will encode values that JSON supports. Objects with values that can be objects, arrays, strings, numbers and booleans. Anything else will be ignored or throw errors. Functions are not a supported entity in JSON. JSON handles pure data only, functions are not data, but behaviour with more complex semantics.
So, basically you need your own reducer and parsers while stringifying and parsing object and that can be done as:
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));
Because Object is a reference type, JSON.parse(JSON.stringify()) returns a new Object, and the == expression compares their address when comparing reference types, so it returns false.
I think the answer to your question can be demonstrated as:
console.log({} == {});
var example = {};
var test = example;
console.log(example == test);
In the first case, we are comparing 2 new empty Objects. Each Object has its own allocation in memory, and so when comparing reference types, this is what is compared. Therefore, false
is returned as they are not the same.
In the second example, we "point" a new variable (test
) to an existing Object (example
). Here we see that it returns true
because this time we are comparing the same memory allocation.