First of all, the answer is probably somewhat different for different JS engines. Also, I assume you're specifically asking about the property storage; obviously objects have a bunch of other state too (prototype chain link being an obvious one).
In the case of Spidermonkey, objects basically have a linked list of (propname, information about property) pairs, until they have too many properties, when I believe they still keep the linked list (because order matters for properties in JS in practice) but add an out-of-band hashtable that maps property names to entries in the linked list.
There may also be other reasons for the switch to the hashtable; the details haven't exactly been fixed over time and are likely subject to change in the future.
The linked lists and hashtables are actually shared across objects; as long as two objects have the same property names and corresponding property information (which does NOT include the value, for properties with a stored value) and the properties were set in the same order, they're able to share the property linked list.
The actual property values, when those need to be stored, are stored in an array in the object (or more precisely, two arrays; one allocated inline with the object, whose size is fixed at object-creation time, one dynamically allocated and resized as needed for properties that are added later).