Let's say we have an apex class we're using as a wrapper object, with a getter method to return an Id made of some derivation of other properties, like so:

Now if you wanted to deliver instances of this class to a javascript-based UI your natural choice would be to create a @RemoteAction method in the page's controller. There's two ways to do this:

  1. Return the wrapper type from the @RemoteAction method and let salesforce handle serialization for you.
  2. Return a pre-serialized JSON string from the method.

The main difference between these two implementations is obvious, the first will return a javascript object to the client, whereas the second will return a string that needs to be passed through JSON.parse before use.

But lo and behold there's another difference in there:

the first approach doesn't have an Id property at all!

The lesson in this:
The implicit serialization provided by @RemoteAction results does not run getter methods.
The explicit serialization of  apex's JSON.serialize does run getter methods.