Search code examples
javascriptundefinedstringify

JavaScript, stringify, replacer - returning undefined vs. returning nothing


I am stringifying an object.

In one case my replacer function returns undefined for all properties (object is sealed):

str = JSON.stringify(o,function(k,v) {
    if(Object.isSealed(this)) {
        return undefined;
    } else {
        return v;
    }
});

in another, it returns nothing at all (both when the object is sealed and when not):

str = JSON.stringify(o,function(k,v) {
    if(Object.isSealed(this)) {
        return undefined;
    }
});

What I'm trying to understand is, why in the first scenario str is "{}", but in the second str is undefined.

Thanks.


Solution

  • If you don't provide an explicit return, the return value is undefined. Your second function always returns undefined, in other words. Because the function always returns undefined, there'll never be anything included in the JSON stringified result, so the overall effect is that you get undefined.

    It's sort-of an anti-pattern to do this:

    if (something) {
      return whatever;
    }
    else {
      return somethingElse;
    }
    

    Your first function would be more idiomatic as:

    str = JSON.stringify(o,function(k,v) {
        return Object.isSealed(this) ? undefined : v;
    });
    

    edit — note that JSON.stringify() calls your replacer function first with an empty key, and "v" equal to this a new wrapper object containing the object to be stringified (and note that that object is not sealed). That is, before checking each property of an object to be stringified, it asks the replacer function whether it should work on the object as a whole. Because your function always returns undefined, the stringify function thinks that there's absolutely nothing to be done. It can't return an empty object because your replacer function immediately told it "don't include this in the result".

    Also note that the caller of your function cannot determine whether your function explicitly returned undefined or if it returned undefined because it didn't return anything, in case that's not clear. Those two cases look exactly the same to the caller.