Steviewevie Steviewevie - 1 month ago 7
Javascript Question

JSON.stringify not returning expected objects

I've been playing about with Node.js and Websockets recently. I'm getting there with it, however there's an odd issue regarding JSON.stringify (client side).

I like to use JSON.stringify to determine which object properties the server is returning..

So for example, I have the following snippet of code:

ws.onmessage = function(param1) {
alert(JSON.stringify(param1));
}


This displays an alert box of
{"isTrusted" : true}


Because of this output, I thought my server wasn't sending a message back to the client. Out of curiousity, I decided to just modify the alert function to

alert(param1.data);


The expected message was there! So my question is why didn't JSON.stringify include a
data
object when it was evidently there?

Answer

JSON.stringify includes only the own, enumerable properties of an object in the output; this is covered by the abstract SerializeJSONObject operation in the spec. That means that inherited properties, and non-enumerable properties, are left out.

Apparently, the only own, enumerable property on your message was isTrusted.

Gratuitous Example:

function Thingy(name, age) {
  // Save `name` as an own, enumerable property
  this.name = name;
  
  // Save `age` as an own, non-enumerable property
  Object.defineProperty(this, "age", {
    value: age
  });
}

// Define `what` as a property that will be inherited by
// all `Thingy` instances:
Thingy.prototype.what = "evs";

// Create one
var t = new Thingy("foo", 42);

// Get the JSON for it:
console.log(JSON.stringify(t)); // {"name":"foo"}


The take-away message here, though, is that there's virtually no place for alert-style debugging in 2016. Instead of stumbling around in the dark with an alert (or console.log) torch, turn on the lights by using the powerful, fully-featured debugger built into your browser: Put a breakpoint on the first statement in your handler, and when the breakpoint is reached, examine the contents of param1 dynamically. It will show you both own properties and inherited ones, enumerable ones and non-enumerable ones, with their current values with the JavaScript code suspended.