Why you should choose composition over inheritance | Javascript OOP Tutorial

  Рет қаралды 14,032

Dave Gray

Dave Gray

Күн бұрын

Web Dev Roadmap for Beginners (Free!): bit.ly/DaveGrayWebDevRoadmap
Why you should choose composition over inheritance when you are creating objects. This tutorial will look at both approaches to creating objects and show you why composition is the best choice as well as the problems that arise with inheritance.
🚩 Subscribe ➜ bit.ly/3nGHmNn
🚀 JavaScript for Beginners: Full Course (8 hours): • JavaScript Full Course...
Advanced Javascript Tutorials mentioned in this video:
🔗 Javascript Classes Tutorial: • Javascript Classes Exp...
🔗 Javascript Prototypes Tutorial: • What is __proto__ ? | ...
🔗 Pure FunctionsTutorial: • What are Pure Function...
🔗 Shallow Copy vs Deep Copy Tutorial: • Shallow Copy and Deep ...
🔗 Decorator Functions Tutorial: • Video
🔗 Currying Functions Tutorial: • How to Curry Functions...
🔗 Source Code: gist.github.com/gitdagray/e34...
Why you should choose composition over inheritance | Javascript OOP Tutorial
(00:00) Intro
(0:18) Problems with object inheritance
(4:45) Composition to the rescue
(10:41) Data structure mutation
(12:51) Cloning to avoid mutation
(16:15) Bonus: Refactoring to a declarative expression
(17:49) Review of Composition
✅ Follow Me:
Twitter: / yesdavidgray
LinkedIn: / davidagray
Blog: yesdavidgray.com
Reddit: / daveoneleven
Was this tutorial about choosing Javascript object composition over inheritance helpful? If so, please share. Let me know your thoughts in the comments.
#composition #inheritance #javascript

Пікірлер: 70
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Javascript Object Composition is preferable to inheritance for keeping your code clean and D.R.Y. In this tutorial, we'll look at examples of some problems with inheritance and how composition can solve those problems. In addition, we'll look at an easy mistake to make when you are working with data structures in objects, and how to avoid that mistake. This is a more advanced tutorial. If you're just starting with Javascript, I suggest checking out my 8 hour full course tutorial on Javascript here: kzbin.info/www/bejne/e5eknWyYrN-JkM0 🚀
@andrewcordoba2411
@andrewcordoba2411 Жыл бұрын
This tutorial is perfect for consolidating deep concepts. Years have passed and it's still good stuff. Good job
@xifrefont1094
@xifrefont1094 Жыл бұрын
I've been looking for a JS tutorial were I could focus on more advanced topics, now that I (believe I) have the foundations. This is gold, been following this tutorial and I'm amazed with the quality of the explanations and the concepts you bring - of which very few I knew before. Thanks a lot, I very rarely leave youtube comments but I felt in the need to thank you for this. I am learning so much!
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Glad it was helpful! 💯
@user-cp4bv5wf1o
@user-cp4bv5wf1o Жыл бұрын
Very laconic explanation! Thank you, sir!
@muneefaltamimi8677
@muneefaltamimi8677 Жыл бұрын
thanks a lot Dave for this amazing explanation!
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
You're welcome!
@voice_famous_books4301
@voice_famous_books4301 8 ай бұрын
nice, great like ever:) Thanks
@jaydenmoon1165
@jaydenmoon1165 Жыл бұрын
I have a solid foundation of knowledge of JavaScript - I honestly love your vids - I always enjoying finding new more advanced ways of working with code - happily subscribed
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Thanks, Jayden! 💯
@larrystone654
@larrystone654 3 жыл бұрын
Great video! Such a clear explanation. At 8:51 could you also use method chaining?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Thank you! 🙏 Good question! At 8:51, I see I was creating an object. In this example, a pizza object needed to be passed in (inside) rather than chained. A little bit later at 9:12 when calling methods, the examples I give will not chain because the methods do not return a result, they just log to the console. You can try to chain the bake() and stuff() methods to see what I mean. The 2nd method cannot call on undefined. If bake() were to return an array for example, you could then chain the array reverse() method to it.
@vasimahmed975
@vasimahmed975 2 жыл бұрын
Concise and on point. I love it. P. S writing a one liner code is a creative experience in itself. Condensing code into is most core form. Kind of like this video actually
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thank you and right on my friend! 💯
@mervinmarias9283
@mervinmarias9283 2 жыл бұрын
Is it better to create the functions inside the global scope, or to create a global object and place everything inside it?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
This is more of an app architecture question, but a good question at the same time. It really depends how your app is structured, but yes, I would say overall, you will want to have some sort of closure over an architecture so globals are not an issue for a variety of reasons. 🚀
@PS-dp8yg
@PS-dp8yg Жыл бұрын
Awesome content! Subscribed. Correct me if I'm wrong, but there is a slight issue doing it this way. Every time you call the create method, those methods are not going to be added to the prototype but the object itself. As a result, if you create two pizzas using createPizza, it will create prepare, bake, and ready twice per object. If it was on the prototype, those methods would be created once and shared among the two pizzas.
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Thank you! Good discussion, but I disagree with composition causing an issue. If you added a method to a prototype - you are once again going back to inheritance. Adding a method to a prototype is like including a method in the createPizza factory function. Both the prototype and the factory function would pass along that method to ALL objects that were created from that base. The other functions (composition) are compared to the extending classes using inheritance.
@PS-dp8yg
@PS-dp8yg Жыл бұрын
@@DaveGrayTeachesCodeDave, Thanks for the response. I totally agree with you about choosing composition over inheritance. Maybe I wasn't clear. When creating a function constructor and wanting to add a method to that function constructor, it needs to be added to its prototype from an efficiency standpoint and save memory. By doing so, each instance can use the same method and not create the same method for each instance created (I'm sure you know all of this). My question and concern were about object literals and adding methods to them. When adding a method to an object literal, does it have the same effect? Do we have to worry about memory when dealing with object literals and adding methods to them? I hope that was clear.
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
I understood overall although I was talking more about design and DRY principles than concern of memory usage - which I now understand was an underlying concern as well. A good article by Eric Elliot on this topic ( medium.com/javascript-scene/why-composition-is-harder-with-classes-c3e627dcd0aa ) A quick quote from the article: "The [[Prototype]] link is used for prototype delegation, which is a convenient way to conserve memory if you have millions of objects, or to squeeze a micro-performance boost out of your program if you need to access tens of thousands of properties on an object within a 16 ms render loop cycle. If you don’t need to micro-optimize memory or performance, the [[Prototype]] link can do more harm than good. "
@PS-dp8yg
@PS-dp8yg Жыл бұрын
@@DaveGrayTeachesCode Thank you! That was an excellent read. Love Eric Elliott. I read his stuff on functional programming.
@sj9851
@sj9851 Жыл бұрын
Class can't do composition? I can imagine a class has these methods and have functions pass in as args.
@stalers2109
@stalers2109 Жыл бұрын
whe u give an object which extends other obejct and u create function which takes and object as parematr and return objects with methods that u want it doesnt really extends the methods from extended class idk why but it doesnt ts just return an object with ur given methods
@venicebeachsurfer
@venicebeachsurfer Жыл бұрын
I get exactly what ur doing, but curious why we just don't pass in a spread'd object to prevent this mutation, ala ``` var origObj = { age: 99, name: 'bill' } function test(w) { w.attribute = true; return w; } console.log(test({...origObj}), origObj); ```
@marcuslorenzo9705
@marcuslorenzo9705 2 жыл бұрын
Hi Dave, I need your help please...you are my primary source of learning! I'm building a serious personal project in React right now, and I'm unsure whether to use inheritance in my program. It's a Boxing Simulator where the user creates an account, which generates a Boxer with 20 attributes of random value. On submission, 30 random boxer-opponents are generated and everything is persisted on the cloud. Boxer profiles, { conditioning, strength, speed, agility, chin, ...others }, Wins, Losses, a ranking system, charts for body and head damage, a full 12 round fight etc...a LOT. Since the "inherent" properties are consistent, is it bad convention to use classes (class constructor) with said web app? Or should I construct my "boxer objects" with full composition, and just have a laundry list of attributes as my arguments? And do I store this as "helper" functions or under a "businessLogic" component? Thank you so much, I've been following you since November of last year!
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Hi Marcus, good questions - and much of the answers are based on personal preference. From this tutorial, you can tell I prefer composition. That said, if you prefer to use inheritance, it is not considered "bad", it is just your preference. You mention you are using React. Your app structure could vary greatly depending on what you are using with it - Context? Redux? React Query? Other state management? etc. - without knowing much about your project, I don't think you would be creating all of those objects within a component. Instead, you may be tracking them with some state as mentioned above.
@matinsasan
@matinsasan 2 жыл бұрын
Usually some say one shouldn't be "opinionated" about one's approach to code, but here you clearly showed how composition owns inheritance in any way, and I wonder what those people could say as a counterargument. You enlightened us in this topic. Thank you, dear mentor. Just one wish: in one comment here you replied about the real use case of inheritance (which again composition owns it whenever its use is possible), I hope it was included in the video as well, as a summary or so.
@zoki5388
@zoki5388 2 жыл бұрын
Hey Dave it seems that source code on github is missing 12:50 onwards. I don't need it but maybe someone in future might need it. and thanks for making great tutorials.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Thanks for the note!
@shineLouisShine
@shineLouisShine Жыл бұрын
05:26 - I can see whay does the pizza (AS AN OBJECT?) gets a prefix of a spread operator, But why do the functions get it as well? - Each function is being called only once for each pizza object, So what is the reason that the spread operator comes before them as well?
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Those functions are being called() and note from above that they return objects... so we are actually spreading the object they return.
@vukkulvar9769
@vukkulvar9769 Жыл бұрын
One caveat is you're creating multiple times the same method. if you don't need to make closures and they're meant to persist, you can change function butter() { return () => console.log("Buttering the crust..."); } { ...butter() } into function butter() { console.log("Buttering the crust..."); } { butter } to save on memory
@mauro1518
@mauro1518 2 жыл бұрын
why you didn't initialized the toppings array in the constructor? what was the reason? and, is there a name or goal or something to do this?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
I am going by memory here without looking at a specific timestamp, but you can add properties to an object using dot notation instead of adding them in a constructor. That is likely what I did.
@mauro1518
@mauro1518 2 жыл бұрын
@@DaveGrayTeachesCode the code i'm referring to is in 0:23, line 6. Well, yes, I know I can add but, the question is, why? Why you did that? Is there any reason to be doing this? Is there like, some particular reason or need or goal to do this?
@prabhu3903
@prabhu3903 2 жыл бұрын
So whats the real use case of using inheritance and classes if everything can be scaled with composition ?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Good question - The suggestion here is to use composition instead. The existence of inheritance is not enough to justify its use. The only reason(s) I can think of where I would use it: 1) You are assigned a legacy code base that uses it or 2) You're on a team that is already using it, so it isn't your choice.
@prabhu3903
@prabhu3903 2 жыл бұрын
@@DaveGrayTeachesCode thank you Mr. Dave
@Liam-ey2gs
@Liam-ey2gs Жыл бұрын
Does anyone know how to make methods or properties private when using composition? Using classes you would prefix the property or method with # making it available only internally
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
You could use closure: kzbin.info/www/bejne/Z4SbhHV6naZqfqM Create a variable that holds a value or function only accessible to the method returned.
@my_vk_vlogs
@my_vk_vlogs 3 жыл бұрын
awesome video
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Thanks! 🚀
@ua2894
@ua2894 5 ай бұрын
how does this work with TS?
@santhoshraghavpidathala3701
@santhoshraghavpidathala3701 3 жыл бұрын
Can you please make a small app using Oops concepts in javascript
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
Yes, I can and should do that. Thanks for the request! 💯🙏
@soniamaklouf1178
@soniamaklouf1178 2 жыл бұрын
Dave when you do return { ...pizza,...prepare(),...bake(),...ready()} you spread the pizza object and all this function in one object. I find it interesting because I've never seen function being spread
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Welcome to functional composition! 😃🚀
@soniamaklouf1178
@soniamaklouf1178 2 жыл бұрын
@@DaveGrayTeachesCode I forgot to say thank you for your work :-) but now I will use the spread operator to clone function in an object when i need it and by the way is it a deep copy I mean if I change the original function will it affect my clone function ?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
@@soniamaklouf1178 the spread operator does not make a deep copy. More on deep copy vs shallow copy here: kzbin.info/www/bejne/anbNYX-tn6h3kLM
@AlexFord
@AlexFord 2 жыл бұрын
What are you using to insert those snippets as you go through the video?
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Good question! I type out the code and then delete it a snippet at a time. Ctrl+Z to undo the delete.
@AlexFord
@AlexFord 2 жыл бұрын
@@DaveGrayTeachesCode haha! Good idea. Thanks 😊
@soichirojin7146
@soichirojin7146 2 жыл бұрын
I like your pizza analogy. Helpful to visualize what is going on. Great tutorial. Thank you.
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
You're welcome! 💯
@andrewevans4722
@andrewevans4722 2 жыл бұрын
I don't see how this is less complicated than inheritance.
@shineLouisShine
@shineLouisShine Жыл бұрын
This is a tough one. Plus, a warning: Do not watch on empty stomach!
@nurettinsen473
@nurettinsen473 2 жыл бұрын
can you share with me to source code
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Hey, thanks for being patient as it has taken me a few days to reply. I created a gist on GitHub for you with the source code: gist.github.com/gitdagray/e3452b267fffb05ee25f0166ab15511f
@nurettinsen473
@nurettinsen473 2 жыл бұрын
@@DaveGrayTeachesCode oh thanks but i already wrote
@djzenma
@djzenma Жыл бұрын
Yes Composition is flexible, but it is too verbose, you have to create every function separately on its own, and then use it to compose something bigger, which when the project gets bigger is hard because you will have too many functions that you don’t know anymore how to use them or what uses them. However, with OOP, you have everything needed in a single place (the class). In short, OOP offers abstraction and encapsulation, which composition clearly lacks. (And I didn’t even mention how you will suffer when you type all these composition functions, you will have to describe the type of every single return type which gets too complicated and too much very fast.)
@DaveGrayTeachesCode
@DaveGrayTeachesCode Жыл бұрын
Nice opposing viewpoint 💯
@kongoulan
@kongoulan Жыл бұрын
Sadly the real life example makes things worse. On this example it seems good, but pizza composition is really not the use cases we face. I think you went to this example, because OOP wants to model real world objects, but then the critizismn is that this is not the way. Obviously even if you code with OOP, you would never create a pizza like that and add functions like toppings.
@minnyanlin2051
@minnyanlin2051 8 ай бұрын
It look like strategy pattern
@minnyanlin2051
@minnyanlin2051 8 ай бұрын
you helped me a lot on learning design pattern
@minnyanlin2051
@minnyanlin2051 8 ай бұрын
thanks @Dave
@emenikedaniel
@emenikedaniel 3 жыл бұрын
Thank you for impacting such detailed knowledge. Just a humble feedback. I m not a pizza person, I was trying to wrap my head around the pizza example and i kind of got lost in it for a few minutes. Maybe u can use a more relatable example asides pizza in more Videos ahead. Thank you Dave💪
@DaveGrayTeachesCode
@DaveGrayTeachesCode 3 жыл бұрын
And I thought food was a universal language 😂... Thanks for the suggestion! I appreciate the feedback 💯
@shanemarchan658
@shanemarchan658 2 жыл бұрын
Hey Dave, big fan of the content. I created maybe a more simple implementation below. let addToppings = (pizza,toppingArr) => { return Object.assign({},pizza,{toppings:toppingArr}) } const davePizzaWithToppings = addToppings(davesPizza, ['olives','cheese'])
@DaveGrayTeachesCode
@DaveGrayTeachesCode 2 жыл бұрын
Nice work Teven! 💯
What is __proto__ ? | Javascript Prototypes Tutorial
23:11
Dave Gray
Рет қаралды 41 М.
Why Favor Object Composition Over Class Inheritance? A Deep Dive
19:00
Зачем он туда залез?
00:25
Vlad Samokatchik
Рет қаралды 2,9 МЛН
ПРОВЕРИЛ АРБУЗЫ #shorts
00:34
Паша Осадчий
Рет қаралды 6 МЛН
What are Pure Functions? | Javascript Functions Tutorial
15:43
Reacting to Controversial Opinions of Software Engineers
9:18
Fireship
Рет қаралды 2 МЛН
OOP Principles: Composition vs Inheritance
15:38
Dave Crabbe
Рет қаралды 51 М.
10 Javascript Functions Examples You Can Use to Save Time
19:15
Object Oriented vs Functional Programming with TypeScript
12:07
WTF is a HOT observable?
9:15
Joshua Morony
Рет қаралды 16 М.
iPhone 15 Pro в реальной жизни
24:07
HUDAKOV
Рет қаралды 407 М.
Зачем ЭТО электрику? #секрет #прибор #энерголикбез
0:56
Александр Мальков
Рет қаралды 622 М.
Easy Art with AR Drawing App - Step by step for Beginners
0:27
Melli Art School
Рет қаралды 15 МЛН
iPhone, Galaxy или Pixel? 😎
0:16
serg1us
Рет қаралды 555 М.
ГОСЗАКУПОЧНЫЙ ПК за 10 тысяч рублей
36:28
Ремонтяш
Рет қаралды 483 М.