3 ms·
How is Object.assign not a "has-a relationship"? From the first article you posted, this example of composition was given: { author: createAuthor(),
by tchaffee 10y ago
How is Object.assign not a "has-a relationship"? From the first article you posted, this example of composition was given:
{
author: createAuthor(),
posts: createPosts()
}
How is that different from this?
Object.assign({}, author, post)
In both cases you end up with an object that has an instance of an author and a post. What am I missing?
- Lazare 10y ago> In both cases you end up with an object that has an instance of an author and a post. But you don't; not even close. The first one is a has-a relationship; the object contains two references (`author` and `posts`), which presumably point to an instance of the Author class and a collection of instances of the Post class (or whatever). This is composition. The second is an is-a relationship; the object has the properties of the author and post objects copied over the top of it. There is now only one object (not three), and if we're lucky, it implements the interface contracts of both the Author class and the Post class. Consider if Author has a title field that contains their preferred prefix (Mr, Ms, Mrs, Dr), and Post has a title field that contains the subject line. With the first approach, we could do `foo.author.title` or `foo.posts[0].title`, using our references to the underlying Author or Post instances. With the second approach, we can do `foo.title` or...`foo.title`. Whups. We have no references, there is no underlying Author or Post instances; there's just a single object which is trying to inherit the behaviour of both the Author and the Post class, and failing. It's not a horrible way of implementing multiple inheritance in JS, but it's still inheritance. And in it's single inheritance form (`Object.assign({}, author)`) it's yields an identical result to normal prototypal inheritance or the class keyword. Edit: This becomes even clearer when you start to flesh out the examples. Eg, https://jsbin.com/kigewonepe/1/edit?js,console https://jsbin.com/kigewonepe/1/edit?js,console Note how obj2 has a `fullName` method (which only Author's do), because it is an author. Except note that it returns the wrong string when you run it, because obj is also a post. Where obj1 works correctly because it has an author and it has a post, without trying to be either of them. Composition over inheritance, just like the Gang of Four said. :)
- tchaffee 10y agoI can get foo.author.title and foo.post.title no problem using Object.assign: Object.assign({}, { author: author }, { post: post }); Can you give a better example of where a reference to an instance is any different than copying an instance? EDIT: I fixed your example. https://jsbin.com/zamuqoropa/1/edit?js,console https://jsbin.com/zamuqoropa/1/edit?js,console EDIT 2: In fact, my Object.assign does exactly the same thing as your example of composition. And console.log(obj1.author === obj2.author); produces 'true'. https://jsbin.com/vafudizumo/1/edit?js,console https://jsbin.com/vafudizumo/1/edit?js,console Either you're doing composition wrong, or I'm not doing inheritance like you are claiming.
- Lazare 10y agoObject.assign({}, { author: author }, { post: post }); Yep, that's composition and it's identical to my composition example. Of course, you're not actually using Object.assign() to do anything; your code is 100% identical to just saying: {author, post}; Not that there's anything wrong with that...but do note that it's also the exact opposite of what Elliott is advocating for, not what he shows off in his code examples, not what his Stampit library does, etc. > Either you're doing composition wrong, or I'm not doing inheritance like you are claiming. Your first example (and Elliott's examples) are inheritance. Your second example is composition. The difference is enormous. Edit: Elliott says here[0] "Similarly, you can use `Object.assign()` to compose any number of objects together with last-in priority:" let ninjamouse = Object.assign({}, mouse, ninja); 1) That's not composition, that's inheritance. 2) That's the same as your first example, but fundamentally different than your second. He's trying to make a "ninjamouse" which has the properties and methods of both mice and ninjas, because it is a mouse and a ninja. (That's inheritance, and it's fragile for all the reasons inheritance is always fragile). Your second example makes an object that has both a mouse and a ninja. That's composition. "This technique is called concatenative inheritance" By absolutely no one ever. :) [0]: https://medium.com/javascript-scene/common-misconceptions-about-inheritance-in-javascript-d5d9bab29b0a#.jw2f0032r https://medium.com/javascript-scene/common-misconceptions-ab...
- 10y ago