Assuming you want c to always mirror a and b, not just at the outset, you can define it with a getter function:
var docs = {
   a: { properties: [1, 2] },
   b: { properties: [3] },
   get c() {
       return { properties: docs.a.properties.concat(docs.b.properties) };
   }
};
console.log(docs.c.properties.join(", ")); // "1, 2, 3"
var docs = {
   a: { properties: [1, 2] },
   b: { properties: [3] },
   get c() { return { properties: docs.a.properties.concat(docs.b.properties) }; }
};
console.log("a: " + JSON.stringify(docs.a));
console.log("b: " + JSON.stringify(docs.b));
console.log("c: " + JSON.stringify(docs.c));
 
 
Note that every access to c will create a new object and a new concatenated array, so it's not particularly efficient. But if you want it to be dynamic...
Or since it's just c.properties that you really need to have a getter:
var docs = {
   a: { properties: [1, 2] },
   b: { properties: [3] },
   c: { get properties() {
           return docs.a.properties.concat(docs.b.properties);
        }
      }
};
console.log(docs.c.properties.join(", ")); // "1, 2, 3"
var docs = {
   a: { properties: [1, 2] },
   b: { properties: [3] },
   c: { get properties() {
           return docs.a.properties.concat(docs.b.properties);
        }
      }
};
console.log("a: " + JSON.stringify(docs.a));
console.log("b: " + JSON.stringify(docs.b));
console.log("c: " + JSON.stringify(docs.c));
 
 
There, just c.properties is recreated each time, not c itself.