I am trying to adopt the new ES6 feature to better compose objects without class inheritance. However, I don't understand how to extend and object or overwrite a function. The code below uses the composition pattern with Object.assign().
Question: How can I create a second object factory UnderlinedCell without copying the whole TextCell object. It behaves like TextCell with the small difference that getHeight returns getHeight + 1 and the draw method adds a line with dashes "-".
Why I want to do this?: I am trying to get my head around the composition concept as explained here in this video Composition over Inheritance from Johansson
Here is the code for the object factory TextCell.
const getHeight = (state) => ({
getHeight: () => state.text.length
})
const draw = (state) => ({
draw: () => state.text.join(" | ")
})
const TextCell = (text) => {
let state = {
text: text.split("\n")
}
return Object.assign(getHeight(state), draw(state))
}
console.log("The height of the cell is %s", TextCell("foo\nbar").getHeight())
console.log(TextCell("foo\nbar").draw())
First of, state
is private. This means we can only do with exposed public methods of TextCell
i.e. getHeight
and draw
.
Now, UnderlineCell
is a function that composes over TextCell
and extends the implementation for TextCell
. e.g.
const getHeight = (state) => ({
getHeight: () => state.text.length
})
const draw = (state) => ({
draw: () => state.text.join(" | ")
})
const TextCell = (text) => {
const state = {
text: text.split("\n")
}
return Object.assign(getHeight(state), draw(state))
}
const UnderlineCell = (text) => {
const textCell = TextCell(text);
const getHeight = () => textCell.getHeight() + 1;
const line = '\n------\n';
const draw = () => textCell.draw().replace(' | ', line) + line;
return {...textCell, getHeight, draw};
}
const uCell = UnderlineCell('hello\nthis');
console.log(uCell.draw());