You can add methods (aka functions) to the objects created from your stamps.
const Logger = stampit({
methods: {
debug(str) {
console.log(str)
}
}
})
const logger = Logger()
logger.debug('Server started')
All the methods are attached to object's prototype.
logger.__proto__.debug === Logger.compose.methods.debug
Moreover, the entire methods
descriptor metadata becomes the prototype.
logger.__proto__ === Logger.compose.methods
If you compose the stamp above with any other stamp, then object instances created from it will also have the .debug
method.
const Server = Logger.compose({
methods: {
async start() {
this.debug('Server started')
}
}
})
const server = Server()
server.debug('Starting server')
server.start()
The methods are copied by assignment. In other words - by reference using Object.assign
.
Logger().debug === Server().debug
In case of conflicts the last composed method wins. To avoid method collision use the @stamp/collision stamp. To make sure a method is implemented use the @stamp/required stamp.
NOTE
When using the @stamp/required stamp it creates a proxy object and returns from the factory. This means that
logger.__proto__ === Logger.compose.methods
orlogger.__proto__.debug === Logger.compose.methods.debug
will no longer betrue
.
Exactly the same stamp can be created in few ways. Here they all are.
function myDebug(str) {
console.log(str)
}
const Logger = stampit({
methods: {
debug: myDebug
}
})
const Logger = stampit.methods({
debug: myDebug
})
const Logger = stampit().methods({
debug: myDebug
})