aphenine
aphenine

Reputation: 1228

JSON.stringify and Object.keys produce different results on same object

I have an issue that isn't making any sense to me. I was wondering if any of you could help.

I have a data source object which I use to access REST data through. All the complex asynchronous stuff works fine, but I've come completely unstuck on what should be the very simple task of passing options into the configuration of the data sources.

At the moment, I have this function:

    object.addSourceOption = function( model, optKey, optVal ){
        if(!_.has(config.sources, model) ){ return this; }
        else{ 
            var options = config.sources[model]["options"];
            options[optKey] = optVal;
            console.log(options[optKey]);
            //options = JSON.parse( JSON.stringify( ) );                
            console.log( "Source Option: " + optKey + ": " + optVal
                         +" added for model: " + model );
            var debugString = JSON.stringify(options);
            console.log(debugString);
            console.log( Object.keys(options));
        }
        return this;
    };

This function is being called and it's being called with good values as far as I can see. Here's an example of some debug output (in this case, the key value is "post_get" and the value is a function, which is printed):

function (element){

    }
restData2.js:189 Source Option: post_get: function (element){

    } added for model: Contacts
restData2.js:191 {}
restData2.js:192 ["post_get"]

I don't understand why JSON.stringify and Objects.keys produce different results. I don't understand which to trust to debug the code I'm using, or what could possibly be happening behind the scenes to make the two functions disagree about the code I've written.

Upvotes: 1

Views: 2078

Answers (2)

Theo Yaung
Theo Yaung

Reputation: 4054

Congratulations! You've found one of the subtler parts of JSON.stringify(...) :)

Here's a helpful part from MDN:

If undefined, a function, or a symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array). JSON.stringify can also just return undefined when passing in "pure" values like JSON.stringify(function(){}) or JSON.stringify(undefined).

While JSON is convenient because it looks like Javascript, JSON is really a subset of Javascript. Moreover, not all JS objects can be represented in JSON. The full details are available at http://json.org/.

But yeah, in your example, post_get is not showing up in the JSON because properties of type function are not legal in JSON.

Hope this helps!

Aside:

Also, keep in mind that sometimes a JS object can have properties that aren't returned by Object.keys(...) either, because Object.keys(...) only returns the properties that were not inherited from any prototypes (base objects) that the object extends.

Upvotes: 2

nnnnnn
nnnnnn

Reputation: 150080

the key value is "post_get" and the value is a function

JSON.stringify() won't include properties that refer to functions. Object.keys() will. It's as simple as that.

Upvotes: 0

Related Questions