Avoiding something that you understand it fully, but disagree with, is wisdom. Avoiding the same thing without understanding it is blind following and/or ignorance. :)
I've been programming for nearly a decade. It is extremely rare to find tutorials that are actually this entertaining. I sat through several episodes on subjects I already knew simply for the entertainment factor, as though I were watching any other youtuber I follow. You sir, are very much appreciated. Thank you.
The lunchtime break is a great addition - It's good to hear your opinions and see a bit of life in Sweden as an interlude. I love the idea that all Swedes go to Ikea for lunch :)
Love being 6 years late to the party, even tho I loved that lunchtime break more. The answer broadened my perspective. I wondered how many people learn to code because it would be an outlet for them to carry out at least some out of many intrusive ideas they have. Probably more than I thought.
One question - in case anybody sees this before I figure it out. If Object.create() itself calls Object.setPrototypeOf() itself, how does it save on performance? I know I must be misunderstanding something fundamental.
One comment to rule them all: I been watching a lot of your vids and it's finally time for me to say....GREAT JOB Really enjoying and appreciate the approach!
Just to remove confusion on the very end chaining remark, adding the `return this` did nothing for the actual lines you chained, returning this from the init function would allow you to call makeSound in a chained way, but you left that unchained. but thats a small remark, i loved the clear explanation, and the way you always try to implement it yourself. that alone makes us understand things way better.
I love concept of constructor function and prototype based OOP inheritance. Much intuitive than forcing to use classes everywhere like Java. And also first-class functions and ES modules really make me like Javascript.
Earlier, it was hard for me to understand what is object creation and how and when we use it.. and your videos were like 20mins .whooopp.. i was like whoooppp..GOD!! but i really enjoyed it.. its funny and cute when ur trying to explain something and u also got confused wt you are saying.. ANYWAYS main thing is Your videos were quite amazing and intersting and now i get it. and i really love your videos now... THANK YOU ..!!!!
Hi there, thanks for your videos. I have a quick question, at the end 17:30, you tried to chain your methods but you didn't really chain them. I was expected something like const mark = Object.create(cat).init('meow').makeSound(). Does it make sense?
Nice video again! Didn't see all your episode yet so I need to do some catching up. Really like your approach of explaining JavaScript topics in a simple non-boring matter. Hopefully you'll spend some time in a episode about the properties options of Object.create. A while ago I was fiddling with Object.create and couldn't figure out why Object.keys wasn't giving back the keys of the just created object (should have read further on MDN ;). So I found out all the properties are by default properties not writable, -> enumerable
Wow man! I probably watched like 15 tutorials on your channel so far. And this whole time I was thinking you are living in Bay area California. The lunch break was a good addition. I really liked it!
"You can think of Douglas Crockford as the grumpy grandfather of JavaScript." If this video was a Medium article, that would definitely be the top highlight.
hi mpj, i have a small question... it's possible to change a prototype after a "Object.create" e refer this change in the new object? something like: const cat = {}; const myCat = Object.creat(cat); cat.eat = () => console.log("eating good"); myCat.eat(); // runtime error ? Thanks, your videos are awesome .. good to learn with you
A great alternative to having an "init" method is to use a... Factory Function! (If factory functions are new to you, I highly recommend THIS video... ruclips.net/video/ImwrezYhw4w/видео.html) To do this, you would write something like: // Still keep the prototype just like before! const cat = { makeSound: function () { console.log(this.sound) } } // But combine the object creation and property initialization steps into one function function Cat (sound) { const self = Object.create(cat) self.sound = sound return self } Now look how much simpler it is if you do this: // Using init() method var mark = Object.create(cat) mark.init('meow') // Using a Factory Function var mark = Cat('meow') 1. You cannot "forget" to call init() 2. You have less to type so its more lazy! 3. You have fewer opportunities to make mistakes, (which by Murphy's Law of Debugging means) you inevitably spend less time debugging! 4. You have made the creation act "atomic". Before, if mark.init('meow') threw an error, you might have ended up with an invalid cat object lying around called mark. By initializing in the factory function before the object is returned, that error can happen before you ever assign a value to mark. This ensures that mark will either be undefined or a valid cat, and not some Schrodinger's semi-created-but-not-initialized cat. 5. You've ABSTRACTED cat creation! This can be a good thing OR a bad thing. Unlike in the init() method version, it's not obvious that mark is a Cat object. Perhaps Cat is just a function that returns true if it succeeded and false if it failed. Or maybe Cat returns the id number of the cat in the cat database. It's no longer immediately clear. BUT let's face it, that cat is going to only get more features, and soon "Object.create()" will be insufficient, and you'll want your Cats to be Immutable or rx.Observable or MongooseDB models, and with a factory function already in place, you won't have to find & replace everywhere you create a cat, because you can just modify the factory function to use something fancier than Object.create().
But at that point, for this contrived example, all you're doing is using the standard constructor pattern, just a bit more desugared. You might as well go all the way and just do: function Cat(sound) { this.sound = sound } Cat.prototype.makeSound = function () { console.log(this.sound) } var mark = new Cat('meow') Even less to type! Factories definitely have their uses and advantages (and they're certainly more explicit about what they're doing, good for newbies trying to get their heads around things), but your example doesn't illustrate these.
"You might as well go all the way and just do" I disagree. Keeping the factory pattern keep things simpler. And simplicity is a worthwhile goal for all programmers, regardless of one's skill level. I would go so far as to say the use of "new" in JavaScript is a code smell. It's not a class-based OO language. It's a functional language at heart. Your code is so much simpler if you embrace using plain-old function calls rather than objects. So I guess really, I should be saying "don't create Objects in JavaScript!" Factories are ultimately more flexible, because you can return other things besides objects - you can return new functions, or promises, or plain-old data. I suppose if you REALLY wanted to use objects, it makes sense to use "new" because the "new" keyword makes it immediately clear that this function will NOT return a promise, or a value, or a callback, etc. Anyway my point is: using a factory function has advantages over a separate "init" step. Using a full-blown constructor and "new" has advantages over the factory pattern. But both are usually overkill and rather than using OO in JS you are probably better off using functions and composing those functions on plain-old data objects.
Thanx for episode. Please go further and explain second argument propertiesObject of Object.create(). What is ownProperties/writable/configurable/getter/setter/etc.
There seems to have been an error during rendering. :) It takes hours for the computer do it so I couldn't re-do it without missing the deadline. It will be back next week!
MPJ, can you please confirm: Adding the 'return this' statement does not really enable the chaining you demonstrated, that would work anyway. What it does do is ensure the mark and waffles values are assigned the correct value so the makeSound calls still work. However, adding 'return this' does enable the chaining of mark.init('mewuuUUF).makeSound() to work.
Don't know if this is the place, but not sure I am getting that concept yet. Can anyone help? Thanks for pointing that out gilmoretj! And Great video MPJ-love the "musing" portions too!
Antonio, This is a bit long so I really hope this helps. Chaining is a common pattern in JavaScript where, for instance, rather than caching an object and repeatedly calling methods on it, each method returns a reference to the object. This enables the methods to be called in sequence off the back of the previous call. In the example given by MPJ (17:12), the mark object was created (using the Object.create method), which made the init and makeSound methods available. By returning the 'this' property, the init function can be used instead of the mark object directly to call the makeSound method. However, the given in the video was not quite chaining and just calling the method. It did not ready make use of the 'return this'. If, on the other hand, MPJ had done mark.init('mewuuUUF').makeSound(), the output would have been the same. In some simple cases chaining can eliminate the need to cache the object at all, even when more than one method needs to be called.
Antonio, From 6:40 in Kyle's video he starts describing the exact same concept. At 8:10 he picks up on one of the use cases for it: rather than making three separate methods calls on the grizzly object, by adding 'return this' to the end of each method, he was able to link (chain) subsequent calls off the return of the previous method call.
I could tell you were Swedish from the way you pronounce "just" :-) Great channel, love your videos! Will be promoting them amongst my junior colleagues.
Love your videos! The conceptual explanation is awesome. Can you please put a link in description for more similar examples that you use in the videos? That will be helpful. Thanks!
Would you mind explaining in more detail why the "new" or "class" implementations are leaky or how they dont map to JS well? I've heard this before but just the generalizations. Thanks.
+Walter Weidner The class instances you create still have a prototype. But I'll try to go into that in the actual class episode, because I think many share your confusion.
MPJ! I really dig the pattern you demonstrated, especially in regards to using the init function. But I have a question about it. Let's say you using this same pattern and from the start had to include a great number of methods on it. Would that take a performance hit? I ask because when using the constructor pattern, I have read in many a source which states, best practice is to apply all the methods to the functions prototype, not as properties to the function (e.g. this.engageWarpDrive = function(){}). But in the end isn't the prototype an object itself? What would make that object different then our cat objects or any Object for that matter? Thanks!!!
Object.create is an incredibly performant and memory efficient way of creating objects. It's the same principle as placing the functions on the .prototype of the function. It is different because the object is only created once, while the constructor is run for every instance. I've talked about this extensively in this series - you might want to go back to the beginning and watch it (or watch it again, and more attentively. :))
Hey Mpj, I'm a professional front-end developer but feel like there's a major lack of learning resources for the higher level developers. I always fall back to MDN for anything I don't know but it would be nice to see more high level tutorials. Do you have any recommendations for higher level javascript tutorials, or things that aren't 'paid' content for the financially strapped developer? I'd like to see some examples of handling, massaging, passing, and working with data in es6 in the future videos. Thanks for the videos I watch them all the time. Also what is the song at 13:12 ?
Super quick question: why don't you seem to use the up/down arrow keys in the terminal? (i.e. to skip back to "node reallylongfilethatishardtotype.js") Also.. did you store a script in objectcreatesample.txt? :)
Fucking love your videos man. They really are a lot of fun (fun, fun...). I just thought I'd let you know, since it looks like you're using VSCode now, you can use Cmd + D to select multiple instances of the same text. Like at around 13:30 when you manually select stuff, you can use the shortcut instead.
@17:33, the function 'create' returns the cat obj, but instead at line 12 it returns that obj to the init function which is the function (init) that returns the cat obj to be assigned to matt?
SO ... well first, great channel, keep it up. Im confused now... Using objects like you have taught, should that be done when trying to stay fun fun functional? Could there be a series where you build something ... one of those 30 things that go in and out your brain? I find it easier to learn when there is a working something at the end. Or maybe a codewars.com series so we can get to see you think through how to solve it and what strategy might be best?
Hi MPJ, This is one of the best channels I have found to learn certain js. Now I have a question as I implement the manipulation of the DOM to the OOP, I am a little confused where to place the addeventlistener inside or outside the object? or for example if I need to store the scrolling level that the user performs to a property of some object as I do it? with this kind of paradigm in JS VANILLA is: window. addeventlistener (' scroll', ()=>{{{) let travelled = (window. scrollY); }) how to do this with OOP ?
Hmm, key point I noticed here, which isn't explained explicitly. It's implied that `Object.setPrototypeOf` is natively slower than `Object.create`, thus the reason we would use the latter instead.
I've read and reread the warning on MDN about `setPrototypeOf()`. I sort of get a feeling that it's only bad when you call it on an object that already has multiple users (or it appears as a prototype in objects that have multiple users downstream). Is it still bad to use it, though, if it's on a freshly created object (possibly within a factory function before the object is returned)? The reason I ask is, `setPrototypeOf()` feels a lot more natural (provided it can be used) than `Object.create()`.
I know JSPerf is not a very good measure of how code behaves in real life, but there's a comparison of _creating_ objects with `Object.create()` vs using `Object.setPrototypeOf()` where `Object.setPrototypeOf()` is either a few % fater or a few % slower depending on the browser. I can't think of a case where real-life object creation would be any more complex than the JSPerf example, though. Please correct me if I'm wrong.
Hi! Great episode once again, I've been watching some of your episodes for a while now and always love your content. Quick note, you chained the wrong methods at the end. Sure you can chain the construction of the object and the first method call which you did. But I think you meant to chain init() and makeSound(), otherwise the return this statement does not do an awful lot for the example. But besides that great stuff, thanks!
Good job MPJ. I have a very basic question.., Am lil bit confused where to use the comma ( used after constructor method) init and were not to ..!??? and do we need to use a semi colon(;) after every line
varun kumar there is actually a video he made about ; The comma is like in a simple object, it separates the properties on the object, in this case the 2 methods
Diamonddeath That's because the cat object is the prototype of Mark. That means all the methods (the functions of an object) of cat is available in Mark.
MPJME, this really gives me sense of inheritance when object.create() returns the obj and we can add more functions/prop to it using the returned object. So if you are in need of creating class kinda functionality, you will use? 1. Class 2. Object Literal with a lot of functions/properties 3. Object.create()
During the last video, I was thinking - but why not use Object.create() ? and so I was happy to see this episode - however, now I wonder - what are your internal rules for when you may use one or the other?
Hi mpj! you should also explain this example) function Person(name, age){ this.name = name; this.age = age; } Person.prototype.sayHi = function(){ console.log('Hi my name is '+ this.name); } const john = new Person('John', 28); john.sayHi(); console.log(Person.isPrototypeOf(john)); //false console.log(john instanceof Person); //true
+Andrew ”Vizantiyec” Bykovets the new keyword video in this series talks about this subject. But basically Person is not a Protoype, it's a function that creates persons, and sets the object Person.prototype as the prototype of the objects it creates. Person.prototype is very confusingly named, a more descriptive name might have been prototypeToUseWhenCreating. So, this would be true: Person.prototype.isPrototypeOf(john);
Awesome video, but why you gotta hate on the propertiesObject (second param of Object.create())? You can both instantiate and set the property 'sound' all within the same call as such: const mark = Object.create(cat, {sound: {value: 'meeeooowwwww'}}); I personally would prefer if the propertiesObject were just standard key-value pair, but I can see how wanting to assign getter/setter methods and define properties such as writable would be useful. I think you're missing out on a lot of functionality found in Object.create if you're not using the propertiesObject.
You can use a standard key-value object literal to set properties if you use Object.assign: const mark = Object.create(cat) Object.assign(mark, { sound: 'meow', legs: 4, color: 'black' }) That way you avoid a long list of `mark. = ...` and don't have to deal with the propertiesObject format, so it's almost the best of both worlds. Unfortunately it's an ES6 method, so you have to worry about compatibility.
@15:30 you mentioned Performance is why we use Prototype, what's that means?Is it because that Object.create is a function already built so we don't need to write our own Objectcreate in browser or what? It's hard to tell which "performance" is good for a newbie >///< and thanks for this great series.
+Frank Hu hi frank. I understand that a lot of beginners have taken up this channel, more than I anticipated, but you are watching this series too early. It is meant to be a deep dive into the object creation of JavaScript for people that have been programming for a few years, but are perhaps just a year into JavaScript.
Thank you so much for putting in all this work. Your really has stepped up online dialogue about software. In a previous episode you mentioned a an amazing redux series which I have struggled to locate. Would you mind posting a link to it? Thank you again.
Annnnd @ 10:48 starts why I never finish anything too. I had a business before, and when people tell me, "you should do a business around that" they don't really know what a business encompasses.
Hi mpj, I would lije to submit the following theme for a future episode of your wonderful series: "Labyrinthine vs Hardwired code": I think you already spoke about that. SInce I've worked 10 years in a worldwide Software editor (Dassault Systems), I always try to code things in a "reusable / extendable / generic / agnostic" mode. This leads to writing much more code than "hardwire then extend" mode. As an example, I currently work on a "hobby project" which is an electron prototype. As I want to setup a configurable for associating a user event (ex: File/Open..., CTRL-O, FileOpen icon in the toolbar) to a command (ex: fileOpenCmd). That's not a big deal, just an example but as I want the menu to be configurable and extendable (even by the user), I then think of having a command factory, which leads to a command registry, then a meta-registry (eg: to get the "plugin registry" because I want the user to be also able to add plugins etc). This sounds good for me but at the same time it's overkill for a nice little tool like one which is just meant for a simple task (ex: a file converter). My question is : "would you tell us some guidelines / rules of thumb to properly adjust the cursor between labyrinthine and hardwired, depending on a project budget and requirements (eg: when/if a project should be broken in sub-projects)
I'm not entirely sure, why you're making videos about inheritance if you think it should never be used :)
Avoiding something that you understand it fully, but disagree with, is wisdom. Avoiding the same thing without understanding it is blind following and/or ignorance. :)
Sounds very Buddha. :)
Just like Religion, lol sorry
sounds like...yoda
@@funfunfunction That's some heavy 'baby Yoda' wisdom there :P
I've been programming for nearly a decade. It is extremely rare to find tutorials that are actually this entertaining. I sat through several episodes on subjects I already knew simply for the entertainment factor, as though I were watching any other youtuber I follow. You sir, are very much appreciated. Thank you.
I love that you leave your typing, deleting, thinking, re-typing, mistakes and corrections in here. It actually makes the process more understandable.
The lunchtime break is a great addition - It's good to hear your opinions and see a bit of life in Sweden as an interlude. I love the idea that all Swedes go to Ikea for lunch :)
Glad you liked the break, I was very happy with it myself.
:) Noo! we do not all go to IKEA for lunch, but it's dirt cheap for sure. You should see the place a rainy weekend after a pay day, its CRAZY!
looked like a long walk how far? no driving? I guess the walk is welcome.
You look like Onision.
Love being 6 years late to the party, even tho I loved that lunchtime break more. The answer broadened my perspective. I wondered how many people learn to code because it would be an outlet for them to carry out at least some out of many intrusive ideas they have. Probably more than I thought.
I'm like 7 hours into a study session and lemme tell you that break to go to ikea was so appreciated. You have a gift for creating videos. Thank you.
One question - in case anybody sees this before I figure it out. If Object.create() itself calls Object.setPrototypeOf() itself, how does it save on performance? I know I must be misunderstanding something fundamental.
Yay finally! I always read blogs of people recommending Object.create over new; but I dont know why.
Hello, mpj! Object.create is a method on Object constructor, not on prototype, as said at 0:29
Oh, great point!
@@funfunfunction Hi. If you agree that there is a mistake here why you haven't add a proper annotation to the video to avoid misleading?
You attitude about the abundance of time is inspiring.
One comment to rule them all:
I been watching a lot of your vids and it's finally time for me to say....GREAT JOB
Really enjoying and appreciate the approach!
Hej Kamel! Thanks for your one comment, and glad to have you following the channel!
Just to remove confusion on the very end chaining remark, adding the `return this` did nothing for the actual lines you chained, returning this from the init function would allow you to call makeSound in a chained way, but you left that unchained.
but thats a small remark, i loved the clear explanation, and the way you always try to implement it yourself. that alone makes us understand things way better.
This is perfectly on point. I'm eagerly awaiting RUclipss new comment system that will allow me to feature comments.
A temporary solution could be to include notes like this in the description.
>Well, if he hadn't returned this from init, then mark would be undefined and mark.makeSound() would throw an error.
thanks for sharing!
what did @Sander mean? I took out "return this" and it returned a TypeError. What does adding a return have to do with chaining?
Liked, Shared, Still Subscribed. Don't know what online JS training would be like without FunFunFunctions.
I love concept of constructor function and prototype based OOP inheritance.
Much intuitive than forcing to use classes everywhere like Java.
And also first-class functions and ES modules really make me like Javascript.
Earlier, it was hard for me to understand what is object creation and how and when we use it.. and your videos were like 20mins .whooopp.. i was like whoooppp..GOD!! but i really enjoyed it.. its funny and cute when ur trying to explain something and u also got confused wt you are saying.. ANYWAYS main thing is Your videos were quite amazing and intersting and now i get it. and i really love your videos now... THANK YOU ..!!!!
Could've done an entire video on the lunch time break question! That was great, as I see myself facing that same dilemma all the time
"House of Leaves" up on the shelf! Props! Thanks for the video and great explanation. :)
Thank's for the switching to the question block in lunch time :) It's first time when I see it, and today's question is really actual :)
Thank you, it's the first time I do it intentionally - glad you liked it!
Has anyone really been far even as decided to use even go want to do look more like?
This video was recommended in The Odin Project Full Stack JavaScript course, great supplement indeed to understand JavaScript Objects!
Your video quality is so good it's almost unnerving. It's like you're here in the room.
thank you! I spend a lot of effort to make it so, glad that it is appreciated!
One more video of yours I'm gonna watch and I'll setup a backspace hit counter. Love the videos by the way!
That middle part about software dev is maturity. You are counting the cost.
Love the music.
Thank you. Very wise comments about what it takes to bring an idea to life and how to view the abundance of time.
man you are so cool and funny...makes learning less tedious and less anxious...keep doing these good stuffs (double thumbs up) :D
Thanks for your time, I am learning a lot with tue video lessons
Hi there, thanks for your videos. I have a quick question, at the end 17:30, you tried to chain your methods but you didn't really chain them. I was expected something like const mark = Object.create(cat).init('meow').makeSound(). Does it make sense?
+Nizar AYARI yeah, as others have pointed out, I made a brain fart.
Nice video again! Didn't see all your episode yet so I need to do some catching up. Really like your approach of explaining JavaScript topics in a simple non-boring matter. Hopefully you'll spend some time in a episode about the properties options of Object.create. A while ago I was fiddling with Object.create and couldn't figure out why Object.keys wasn't giving back the keys of the just created object (should have read further on MDN ;). So I found out all the properties are by default properties not writable, -> enumerable
I really liked your way of teaching , it is really funny and unexpected
Wow man! I probably watched like 15 tutorials on your channel so far. And this whole time I was thinking you are living in Bay area California. The lunch break was a good addition. I really liked it!
"You can think of Douglas Crockford as the grumpy grandfather of JavaScript."
If this video was a Medium article, that would definitely be the top highlight.
Just. Love. The lunch break. Gimme more.
hi mpj, i have a small question... it's possible to change a prototype after a "Object.create" e refer this change in the new object?
something like:
const cat = {};
const myCat = Object.creat(cat);
cat.eat = () => console.log("eating good");
myCat.eat(); // runtime error ?
Thanks, your videos are awesome .. good to learn with you
I like how educational javascript video accidentally turns out into an Ikea lunch vlog
Love your videos!!
To clarify: you can use either Object.create() with any object as its argument? You don't need to have used a constructor function?
Studying JS and prototype inheritance, this episode was very helpful.
I like your videos a lot. You explain many things and explain those things very well.
Lets go, Odin Project gang!!
awesome! fun fun function is really worth the subscription !
A great alternative to having an "init" method is to use a... Factory Function! (If factory functions are new to you, I highly recommend THIS video... ruclips.net/video/ImwrezYhw4w/видео.html) To do this, you would write something like:
// Still keep the prototype just like before!
const cat = {
makeSound: function () { console.log(this.sound) }
}
// But combine the object creation and property initialization steps into one function
function Cat (sound) {
const self = Object.create(cat)
self.sound = sound
return self
}
Now look how much simpler it is if you do this:
// Using init() method
var mark = Object.create(cat)
mark.init('meow')
// Using a Factory Function
var mark = Cat('meow')
1. You cannot "forget" to call init()
2. You have less to type so its more lazy!
3. You have fewer opportunities to make mistakes, (which by Murphy's Law of Debugging means) you inevitably spend less time debugging!
4. You have made the creation act "atomic". Before, if mark.init('meow') threw an error, you might have ended up with an invalid cat object lying around called mark. By initializing in the factory function before the object is returned, that error can happen before you ever assign a value to mark. This ensures that mark will either be undefined or a valid cat, and not some Schrodinger's semi-created-but-not-initialized cat.
5. You've ABSTRACTED cat creation! This can be a good thing OR a bad thing. Unlike in the init() method version, it's not obvious that mark is a Cat object. Perhaps Cat is just a function that returns true if it succeeded and false if it failed. Or maybe Cat returns the id number of the cat in the cat database. It's no longer immediately clear. BUT let's face it, that cat is going to only get more features, and soon "Object.create()" will be insufficient, and you'll want your Cats to be Immutable or rx.Observable or MongooseDB models, and with a factory function already in place, you won't have to find & replace everywhere you create a cat, because you can just modify the factory function to use something fancier than Object.create().
But at that point, for this contrived example, all you're doing is using the standard constructor pattern, just a bit more desugared. You might as well go all the way and just do:
function Cat(sound) { this.sound = sound }
Cat.prototype.makeSound = function () { console.log(this.sound) }
var mark = new Cat('meow')
Even less to type!
Factories definitely have their uses and advantages (and they're certainly more explicit about what they're doing, good for newbies trying to get their heads around things), but your example doesn't illustrate these.
"You might as well go all the way and just do"
I disagree. Keeping the factory pattern keep things simpler. And simplicity is a worthwhile goal for all programmers, regardless of one's skill level. I would go so far as to say the use of "new" in JavaScript is a code smell. It's not a class-based OO language. It's a functional language at heart. Your code is so much simpler if you embrace using plain-old function calls rather than objects.
So I guess really, I should be saying "don't create Objects in JavaScript!" Factories are ultimately more flexible, because you can return other things besides objects - you can return new functions, or promises, or plain-old data. I suppose if you REALLY wanted to use objects, it makes sense to use "new" because the "new" keyword makes it immediately clear that this function will NOT return a promise, or a value, or a callback, etc.
Anyway my point is: using a factory function has advantages over a separate "init" step. Using a full-blown constructor and "new" has advantages over the factory pattern. But both are usually overkill and rather than using OO in JS you are probably better off using functions and composing those functions on plain-old data objects.
This is great I am using this.
Thanx for episode.
Please go further and explain second argument propertiesObject of Object.create(). What is ownProperties/writable/configurable/getter/setter/etc.
As usual.. great content, lots of humor and a fun approach. Keep up the good work master :)
I shall keep up the good work, even though I'm no master. :) Glad to have you following the channel, Daniel!
No! You broke my routine! Where is "Goood Monday mornig? I'm MPJ and you are watching..."? Is it muted? Hahaha! Amazing one as always. Thanks!
There seems to have been an error during rendering. :) It takes hours for the computer do it so I couldn't re-do it without missing the deadline. It will be back next week!
Definitely linear explanation, clear, and nice. Thanks.
Subscribed. Grumpy grandfather of JavaScript. lol
MPJ, can you please confirm: Adding the 'return this' statement does not really enable the chaining you demonstrated, that would work anyway. What it does do is ensure the mark and waffles values are assigned the correct value so the makeSound calls still work. However, adding 'return this' does enable the chaining of mark.init('mewuuUUF).makeSound() to work.
Ah, yeah, you're completely right.
Don't know if this is the place, but not sure I am getting that concept yet. Can anyone help? Thanks for pointing that out gilmoretj! And Great video MPJ-love the "musing" portions too!
Antonio, This is a bit long so I really hope this helps.
Chaining is a common pattern in JavaScript where, for instance, rather than caching an object and repeatedly calling methods on it, each method returns a reference to the object. This enables the methods to be called in sequence off the back of the previous call.
In the example given by MPJ (17:12), the mark object was created (using the Object.create method), which made the init and makeSound methods available. By returning the 'this' property, the init function can be used instead of the mark object directly to call the makeSound method. However, the given in the video was not quite chaining and just calling the method. It did not ready make use of the 'return this'.
If, on the other hand, MPJ had done mark.init('mewuuUUF').makeSound(), the output would have been the same. In some simple cases chaining can eliminate the need to cache the object at all, even when more than one method needs to be called.
Antonio, From 6:40 in Kyle's video he starts describing the exact same concept. At 8:10 he picks up on one of the use cases for it: rather than making three separate methods calls on the grizzly object, by adding 'return this' to the end of each method, he was able to link (chain) subsequent calls off the return of the previous method call.
Thanks Gilmoretj! Would you say in your opinion, it makes sense to apply this approach essentially only to methods of an Object?
node filename without the .js ext will work as well:) great content!
+hal7mar great point, I had completely forgotten that!
Love the way of your teaching, best tutorial
I could tell you were Swedish from the way you pronounce "just" :-)
Great channel, love your videos! Will be promoting them amongst my junior colleagues.
Love your videos! The conceptual explanation is awesome. Can you please put a link in description for more similar examples that you use in the videos? That will be helpful. Thanks!
Would you mind explaining in more detail why the "new" or "class" implementations are leaky or how they dont map to JS well? I've heard this before but just the generalizations. Thanks.
+Walter Weidner The class instances you create still have a prototype. But I'll try to go into that in the actual class episode, because I think many share your confusion.
MPJ! I really dig the pattern you demonstrated, especially in regards to using the init function.
But I have a question about it. Let's say you using this same pattern and from the start had to include a great number of methods on it. Would that take a performance hit?
I ask because when using the constructor pattern, I have read in many a source which states, best practice is to apply all the methods to the functions prototype, not as properties to the function (e.g. this.engageWarpDrive = function(){}). But in the end isn't the prototype an object itself? What would make that object different then our cat objects or any Object for that matter?
Thanks!!!
Object.create is an incredibly performant and memory efficient way of creating objects. It's the same principle as placing the functions on the .prototype of the function. It is different because the object is only created once, while the constructor is run for every instance. I've talked about this extensively in this series - you might want to go back to the beginning and watch it (or watch it again, and more attentively. :))
0:40 Thank god for youtube because i feel like that every time i read documentation about something new
Hey Mpj, I'm a professional front-end developer but feel like there's a major lack of learning resources for the higher level developers. I always fall back to MDN for anything I don't know but it would be nice to see more high level tutorials. Do you have any recommendations for higher level javascript tutorials, or things that aren't 'paid' content for the financially strapped developer? I'd like to see some examples of handling, massaging, passing, and working with data in es6 in the future videos. Thanks for the videos I watch them all the time. Also what is the song at 13:12 ?
Hey mate, thanks for the video, great explanation as always and very cool music, in line with the spirit of the show! Thanks for doing this
Thx mpj! Love your vids.
Super quick question: why don't you seem to use the up/down arrow keys in the terminal? (i.e. to skip back to "node reallylongfilethatishardtotype.js")
Also.. did you store a script in objectcreatesample.txt? :)
I avoid hotkeys and fast-typing to make it easier to follow.
(and I misspelled the file when I created it, there is an objectcreatesample.ks) :)
Very great series, thanks. hope you add new great episodes to this series as well.
I love this guy very much! Thank you for awesome and very useful videos!
Fucking love your videos man. They really are a lot of fun (fun, fun...).
I just thought I'd let you know, since it looks like you're using VSCode now, you can use Cmd + D to select multiple instances of the same text. Like at around 13:30 when you manually select stuff, you can use the shortcut instead.
Yeah, I know. :) It's like my one dealbreaker hotkey. I just don't use a lot of hotkeys when I do screencaps.
Ah I thought you would, but always good to spread info around :)
@17:33, the function 'create' returns the cat obj, but instead at line 12 it returns that obj to the init function which is the function (init) that returns the cat obj to be assigned to matt?
SO ... well first, great channel, keep it up.
Im confused now... Using objects like you have taught, should that be done when trying to stay fun fun functional?
Could there be a series where you build something ... one of those 30 things that go in and out your brain? I find it easier to learn when there is a working something at the end.
Or maybe a codewars.com series so we can get to see you think through how to solve it and what strategy might be best?
Hi MPJ, This is one of the best channels I have found to learn certain js. Now I have a question as I implement the manipulation of the DOM to the OOP, I am a little confused where to place the addeventlistener inside or outside the object? or for example if I need to store the scrolling level that the user performs to a property of some object as I do it? with this kind of paradigm in JS VANILLA is:
window. addeventlistener (' scroll', ()=>{{{)
let travelled = (window. scrollY);
})
how to do this with OOP ?
Hmm, key point I noticed here, which isn't explained explicitly. It's implied that `Object.setPrototypeOf` is natively slower than `Object.create`, thus the reason we would use the latter instead.
Thanks! Great mpj! Simple explanation :D
0:25
I wouldn't say that Object.create sits inside prototype, as it's not being inherited by newly created objects.
Thank you MPJ
Is there a way to see the implementation of these functions in the browser?
I've read and reread the warning on MDN about `setPrototypeOf()`. I sort of get a feeling that it's only bad when you call it on an object that already has multiple users (or it appears as a prototype in objects that have multiple users downstream). Is it still bad to use it, though, if it's on a freshly created object (possibly within a factory function before the object is returned)? The reason I ask is, `setPrototypeOf()` feels a lot more natural (provided it can be used) than `Object.create()`.
I know JSPerf is not a very good measure of how code behaves in real life, but there's a comparison of _creating_ objects with `Object.create()` vs using `Object.setPrototypeOf()` where `Object.setPrototypeOf()` is either a few % fater or a few % slower depending on the browser. I can't think of a case where real-life object creation would be any more complex than the JSPerf example, though. Please correct me if I'm wrong.
Hey MPJ! Can you tell me which syntax highlighting theme you're using? I love it!
Thanks for your videos, they are so useful :)
cobalt2!
Thanks! While the js syntax looks cool, I don't like the html and sass aspect of it, such a shame!
Hi!
Great episode once again, I've been watching some of your episodes for a while now and always love your content.
Quick note, you chained the wrong methods at the end. Sure you can chain the construction of the object and the first method call which you did. But I think you meant to chain init() and makeSound(), otherwise the return this statement does not do an awful lot for the example.
But besides that great stuff, thanks!
Good job MPJ. I have a very basic question.., Am lil bit confused where to use the comma ( used after constructor method) init and were not to ..!??? and do we need to use a semi colon(;) after every line
varun kumar there is actually a video he made about ;
The comma is like in a simple object, it separates the properties on the object, in this case the 2 methods
I checked out your videos on "this" and am still confused on why something like mark.makeSound() is looking into const cat
Diamonddeath That's because the cat object is the prototype of Mark. That means all the methods (the functions of an object) of cat is available in Mark.
I think I get it. Thanks.
MPJME, this really gives me sense of inheritance when object.create() returns the obj and we can add more functions/prop to it using the returned object.
So if you are in need of creating class kinda functionality, you will use?
1. Class
2. Object Literal with a lot of functions/properties
3. Object.create()
I almost always use 2. The factory function video represents pretty well how I do it.
Love your shows!
During the last video, I was thinking - but why not use Object.create() ? and so I was happy to see this episode - however, now I wonder - what are your internal rules for when you may use one or the other?
Great video as usual, I'll try to use more prototyping in my js in the future
Hi mpj! you should also explain this example)
function Person(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
console.log('Hi my name is '+ this.name);
}
const john = new Person('John', 28);
john.sayHi();
console.log(Person.isPrototypeOf(john)); //false
console.log(john instanceof Person); //true
+Andrew ”Vizantiyec” Bykovets the new keyword video in this series talks about this subject. But basically Person is not a Protoype, it's a function that creates persons, and sets the object Person.prototype as the prototype of the objects it creates. Person.prototype is very confusingly named, a more descriptive name might have been prototypeToUseWhenCreating.
So, this would be true:
Person.prototype.isPrototypeOf(john);
How does the actual implementation of Object.create work if it doesn't use Object.setPrototypeOf?
Great Video!
Why did the terminal doesn't complete the .js extension? haha do you have the .coffee version or the .ts version?
+Victor Huerta I accidentally created a .ks version prior to starting the video and could not be bothered to delete it. :)
Hi mpj, great job on the videos, really enjoying them. Can you make a video on the topic of Singletons? Thanks in advance.
Different patterns is indeed an idea. We'll see.
MPJ, an Idea! An episode on Gulp would be great.
thank you for the clear explnation!
Great channel and great videos. Thanks for sharing good stuff like these!
Nice series - very informative! Thanks!
Personally liked the sound of rain, but I hope this isn't the case in your next vids hahaha. I'm worried for the camera (you might get sick too)
Respect from India.
Awesome video, but why you gotta hate on the propertiesObject (second param of Object.create())? You can both instantiate and set the property 'sound' all within the same call as such:
const mark = Object.create(cat, {sound: {value: 'meeeooowwwww'}});
I personally would prefer if the propertiesObject were just standard key-value pair, but I can see how wanting to assign getter/setter methods and define properties such as writable would be useful. I think you're missing out on a lot of functionality found in Object.create if you're not using the propertiesObject.
You can use a standard key-value object literal to set properties if you use Object.assign:
const mark = Object.create(cat)
Object.assign(mark, {
sound: 'meow',
legs: 4,
color: 'black'
})
That way you avoid a long list of `mark. = ...` and don't have to deal with the propertiesObject format, so it's almost the best of both worlds. Unfortunately it's an ES6 method, so you have to worry about compatibility.
What's the difference between object.create and Object Literal? The syntax looks the same to me. Am I missing something?
+Diamonddeath Object.create allows you to specify a prototype. It also has some other features I don't go ov
Great explanation, thanks!
Bizarre question -- where did you get the phrase "Grumpy Grandfather of Javascript"? That's the second time I've heard someone call Crockford that.
I have no idea where I heard it - I definitely did not make it up myself.
I find the music during the fast-tracking a bit distracting from actually taking in what you are writing. Maybe that's just me though. :)
MPJ, really loving your videos. You make learning JS so much fun and I look forward to your posts. Just wish you'd post more than once a week!
You might have talked about this before, but is there a reason you do not use semicolons at the end of statements?
+Rahul Goma Phulore look at the semicolons episode
Thank you!
@15:30 you mentioned Performance is why we use Prototype, what's that means?Is it because that Object.create is a function already built so we don't need to write our own Objectcreate in browser or what?
It's hard to tell which "performance" is good for a newbie >///< and thanks for this great series.
+Frank Hu hi frank. I understand that a lot of beginners have taken up this channel, more than I anticipated, but you are watching this series too early. It is meant to be a deep dive into the object creation of JavaScript for people that have been programming for a few years, but are perhaps just a year into JavaScript.
Thank you for your vid man, appreciate it man :) have a nice day man :)
Thank you so much for putting in all this work. Your really has stepped up online dialogue about software. In a previous episode you mentioned a an amazing redux series which I have struggled to locate. Would you mind posting a link to it? Thank you again.
+Rony Sheer Wes bos
Thank you so much!
no problem!
good morning monday!
Annnnd @ 10:48 starts why I never finish anything too. I had a business before, and when people tell me, "you should do a business around that" they don't really know what a business encompasses.
how can you create some sort of factory function to create multiple objects of a certain blueprint?
Hi mpj, I would lije to submit the following theme for a future episode of your wonderful series:
"Labyrinthine vs Hardwired code": I think you already spoke about that. SInce I've worked 10 years in a worldwide Software editor (Dassault Systems), I always try to code things in a "reusable / extendable / generic / agnostic" mode. This leads to writing much more code than "hardwire then extend" mode.
As an example, I currently work on a "hobby project" which is an electron prototype. As I want to setup a configurable for associating a user event (ex: File/Open..., CTRL-O, FileOpen icon in the toolbar) to a command (ex: fileOpenCmd). That's not a big deal, just an example but as I want the menu to be configurable and extendable (even by the user), I then think of having a command factory, which leads to a command registry, then a meta-registry (eg: to get the "plugin registry" because I want the user to be also able to add plugins etc). This sounds good for me but at the same time it's overkill for a nice little tool like one which is just meant for a simple task (ex: a file converter).
My question is :
"would you tell us some guidelines / rules of thumb to properly adjust the cursor between labyrinthine and hardwired, depending on a project budget and requirements (eg: when/if a project should be broken in sub-projects)
Mpj can you do a video explaning the difference between object.create and object.assign?
Where do you get such awesome music from?