But Stamps are a little different. They carry around the metadata about the object they are going to produce. The metadata is attached to the Stamp.compose object:
functionStamp () {constmetadata=Stamp.compose // retrieving metadata from itself...SNIP...return newObject}
There are 11 standardized types of metadata, such as properties and deepProperties.
functionStamp () {constmetadata=Stamp.compose // retrieving metadata from itselfconstproperties=metadata.properties // retrieving properties from the metadatalet deepProperties =metadata.deepProperties // retrieving deepProperties from the metadata deepProperties =JSON.parse(JSON.stringify(deepProperties)) // we need to clone deepPropertiesconstnewObject=Object.assign({}, deepProperties, properties) // creating new object using the properties...SNIP...return newObject}
There is also methods object which becomes the new object's prototype.
functionStamp () {constmetadata=Stamp.compose // retrieving metadata from itselfconstproperties=metadata.properties // retrieving properties from the metadatalet deepProperties =metadata.deepProperties // retrieving deepProperties from the metadata deepProperties =_.cloneDeep(deepProperties) // we need to clone deepPropertiesconstnewObject=Object.assign({}, deepProperties, properties) // creating new object using the propertiesconstmethods=metadata.methods // retrieving methods from the metadataif (methods) Object.setPrototypeOf(newObject, methods) // assigning new object's prototype...SNIP...return newObject}
The propertyDescriptors metadata is an object applied to the resulting object using Object.defineProperties JavaScript standard function.
functionStamp () {constmetadata=Stamp.compose // retrieving metadata from itselfconstproperties=metadata.properties // retrieving properties from the metadatalet deepProperties =metadata.deepProperties // retrieving deepProperties from the metadata deepProperties =JSON.parse(JSON.stringify(deepProperties)) // we need to clone deepPropertiesconstnewObject=Object.assign({}, deepProperties, properties) // creating new object using the propertiesconstmethods=metadata.methods // retrieving methods from the metadataif (methods) Object.setPrototypeOf(newObject, methods) // assigning new object's prototypeObject.defineProperties(newObject,metadata.propertyDescriptors)...SNIP...return newObject}
Last, but not least, the initializers are kind of constructors. With classic classes you would execute only one constructor when creating an object. With stamps you execute all the initializers of a stamp.
functionStamp () {constmetadata=Stamp.compose // retrieving metadata from itselfconstproperties=metadata.properties // retrieving properties from the metadatalet deepProperties =metadata.deepProperties // retrieving deepProperties from the metadata deepProperties =JSON.parse(JSON.stringify(deepProperties)) // we need to clone deepPropertiesconstnewObject=Object.assign({}, deepProperties, properties) // creating new object using the propertiesconstmethods=metadata.methods // retrieving methods from the metadataif (methods) Object.setPrototypeOf(newObject, methods) // assigning new object's prototypeObject.defineProperties(newObject,metadata.propertyDescriptors)for (constinitofmetadata.initializers || []) { // run every initializer one by oneconstfirstArg= argument[0]constsecondArg= { args: [...arguments], instance: newObject, stamp: Stamp }constreturnedValue=init.call(newObject, firstArg, secondArg)if (returnedValue !==undefined) { newObject = returnedValue } }return newObject}
If an initializer returns a non-undefined value then it becomes the new object instance.