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 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!
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.
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.
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.
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 ..!!!!
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!
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
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?
@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?
Thanx for episode. Please go further and explain second argument propertiesObject of Object.create(). What is ownProperties/writable/configurable/getter/setter/etc.
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.
"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.
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.
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.
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
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.
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()
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.
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 ?
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.
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?
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!
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.
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.
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
@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.
what is the use of \''+ in javascript??? i am including the line below where i found this thing var loopTimer=setTimeout('fadeOut(\''+element+'\')',50); please respond
Mind blown. setTimeout can accept a string as argument, and execute it the same way as eval. DO NOT DO THIS unless you really, really know what you are doing. The line you posted is very bad practice. But to your question: the backslashes do not have JavaScript significance per se, they are just escaping (skipping) the next character in the string, so that you can write strings inside of the string, so to speak.
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! 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!
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.
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 have a question about const var, isn't const obj not allowed to add new property after it's declared? What make's the different behavior of const foo = Object.create(...) foo.newProperty = propertyVal?
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. :))
Олег Корецкий As long as you are working with prototypes and not classes, Yes! The next question is why anyone would want to work with classes but that's another....question.
There is no clear best way. You just have to evaluate the options and find what works best for you and your team. This way is a lot more natural to JavaScript and it's much more obvious what is happening. The ES6 class keyword is a thin veil of syntactic sugar over the more complicated "new applied to functions" style in earlier episodes - it will look more familiar to people from a C# background, for instance, so if your team is composed of C#ers migrating to JS it might be a good idea. It is, however, a pretty leaky abstraction and there is still the prototype underneath, so I personally think it's better to go for the real thing.
Some more food for thought. The Object.create(type).init(args) pattern presented here is one you'll probably use a lot. Every time you want to make a new object, in fact. And if ever you forget to call init, if you leave an object uninitialized, that would almost certainly be a mistake. So let's prevent that mistake by bundling those operations into a single function. function make(type, ...args) { const o = Object.create(type) o.init(...args) return o } const waffles = make(cat, 'meow') // both creates and inits This seems handy, except... wait... we just re-implemented "new"! Even though some people are absolutely convinced that "new" is terrible and evil, we still end up doing the same thing anyway. So the only difference is which syntax you like better and how many built-in features we want to re-implement. const cat = { init: function(sound) { this.sound = sound; }, makeSound: function() { console.log(this.sound) } } const waffles = Object.create(cat).init('meow') ...or... class Cat { constructor(sound) { this.sound = sound; } makeSound() { console.log(this.sound) } } const waffles = new Cat('meow') Notice the structure in both examples is basically identical. Only names and labels changed. Keep this in mind the next time someone tells you classes are bad. The anti-class solutions still end up doing the same thing.
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.
Short question: What's your opinion on the new class syntax in ES2015? My own is not too favorable, for some of the reasons you lay out in this video as reasons to prefer Object.create() to the 'new' syntax. It obscures what you're actually looking at, an object with a prototype, by making it look like an OOP class.
How so? The ES2015 class syntax doesn't replace 'new' after all. It does somewhat replace the Object.create(proto).init(props) flow you demonstrated (which is a nice and clear flow, BTW), but using a sugar for the old -function StuffClass() {...}; Object.setPrototypeOf(StuffClass, proto); new StuffClass(props);- (LOLwrong) flow. EDIT: I was thinking of this flow: function StuffClass() {} StuffClass.prototype = proto; new StuffClass(props);
Right. True. This further adds to the confusion. >.< The class syntax doesn't seem much of a step up, though. Doesn't much solve the fundamental problem of obscuring what happens.
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.
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 love that you leave your typing, deleting, thinking, re-typing, mistakes and corrections in here. It actually makes the process more understandable.
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!
Yay finally! I always read blogs of people recommending Object.create over new; but I dont know why.
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.
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.
You attitude about the abundance of time is inspiring.
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?
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?
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?
man you are so cool and funny...makes learning less tedious and less anxious...keep doing these good stuffs (double thumbs up) :D
"House of Leaves" up on the shelf! Props! Thanks for the video and great explanation. :)
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
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!
This video was recommended in The Odin Project Full Stack JavaScript course, great supplement indeed to understand JavaScript Objects!
Love the music.
One more video of yours I'm gonna watch and I'll setup a backspace hit counter. Love the videos by the way!
Thank you. Very wise comments about what it takes to bring an idea to life and how to view the abundance of time.
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!
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
Thanks for your time, I am learning a lot with tue video lessons
I really liked your way of teaching , it is really funny and unexpected
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!
I like your videos a lot. You explain many things and explain those things very well.
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.
@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?
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
Thanx for episode.
Please go further and explain second argument propertiesObject of Object.create(). What is ownProperties/writable/configurable/getter/setter/etc.
Love the way of your teaching, best tutorial
awesome! fun fun function is really worth the subscription !
Studying JS and prototype inheritance, this episode was very helpful.
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.
Thanks! Great mpj! Simple explanation :D
Just. Love. The lunch break. Gimme more.
Very great series, thanks. hope you add new great episodes to this series as well.
Definitely linear explanation, clear, and nice. Thanks.
I love this guy very much! Thank you for awesome and very useful videos!
node filename without the .js ext will work as well:) great content!
+hal7mar great point, I had completely forgotten that!
Subscribed. Grumpy grandfather of JavaScript. lol
"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.
I like how educational javascript video accidentally turns out into an Ikea lunch vlog
Great channel and great videos. Thanks for sharing good stuff like these!
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.
Great video as usual, I'll try to use more prototyping in my js in the future
Thx mpj! Love your vids.
0:25
I wouldn't say that Object.create sits inside prototype, as it's not being inherited by newly created objects.
Lets go, Odin Project gang!!
Nice series - very informative! Thanks!
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.
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
That middle part about software dev is maturity. You are counting the cost.
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.
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 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?
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?
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 ?
Thank you for your vid man, appreciate it man :) have a nice day man :)
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 :)
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!
how can you create some sort of factory function to create multiple objects of a certain blueprint?
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?
What if you want to apply multiple prototypes to an object, like multiple inheritance?
Love your shows!
thank you for the clear explnation!
Thank you MPJ
Is there a way to see the implementation of these functions in the browser?
Respect from India.
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.
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!
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 does the actual implementation of Object.create work if it doesn't use Object.setPrototypeOf?
Great Video!
please make a video on constructor property and why it is required. thanks
Great explanation, thanks!
Thanks for another great video!!
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!
0:40 Thank god for youtube because i feel like that every time i read documentation about something new
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
@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.
what is the use of \''+ in javascript???
i am including the line below where i found this thing
var loopTimer=setTimeout('fadeOut(\''+element+'\')',50);
please respond
Mind blown. setTimeout can accept a string as argument, and execute it the same way as eval.
DO NOT DO THIS unless you really, really know what you are doing. The line you posted is very bad practice.
But to your question: the backslashes do not have JavaScript significance per se, they are just escaping (skipping) the next character in the string, so that you can write strings inside of the string, so to speak.
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?
Mpj can you do a video explaning the difference between object.create and object.assign?
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!
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.
What is the colorful theme name in that editor?
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) :)
Can you explain what the key differences between the 'new' and object.Create patterns are?
+James Riall that is what this series does. :) did you watch it from the start?
Fun Fun Function Obviously not closely enough 🙄😅
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!
I have a question about const var, isn't const obj not allowed to add new property after it's declared? What make's the different behavior of
const foo = Object.create(...)
foo.newProperty = propertyVal?
const merely merely makes the reference constant, it does not place any restrictions on the object itself.
Got it, I had misconception of const objs, thanks mate!
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. :))
MPJ, an Idea! An episode on Gulp would be great.
Should I use this approach to objects if in ES6 there is a "class" keyword?
Олег Корецкий As long as you are working with prototypes and not classes, Yes! The next question is why anyone would want to work with classes but that's another....question.
There is no clear best way. You just have to evaluate the options and find what works best for you and your team. This way is a lot more natural to JavaScript and it's much more obvious what is happening. The ES6 class keyword is a thin veil of syntactic sugar over the more complicated "new applied to functions" style in earlier episodes - it will look more familiar to people from a C# background, for instance, so if your team is composed of C#ers migrating to JS it might be a good idea. It is, however, a pretty leaky abstraction and there is still the prototype underneath, so I personally think it's better to go for the real thing.
Thanks a lot!
Some more food for thought. The Object.create(type).init(args) pattern presented here is one you'll probably use a lot. Every time you want to make a new object, in fact. And if ever you forget to call init, if you leave an object uninitialized, that would almost certainly be a mistake. So let's prevent that mistake by bundling those operations into a single function.
function make(type, ...args) {
const o = Object.create(type)
o.init(...args)
return o
}
const waffles = make(cat, 'meow') // both creates and inits
This seems handy, except... wait... we just re-implemented "new"! Even though some people are absolutely convinced that "new" is terrible and evil, we still end up doing the same thing anyway. So the only difference is which syntax you like better and how many built-in features we want to re-implement.
const cat = {
init: function(sound) {
this.sound = sound;
},
makeSound: function() {
console.log(this.sound)
}
}
const waffles = Object.create(cat).init('meow')
...or...
class Cat {
constructor(sound) {
this.sound = sound;
}
makeSound() {
console.log(this.sound)
}
}
const waffles = new Cat('meow')
Notice the structure in both examples is basically identical. Only names and labels changed. Keep this in mind the next time someone tells you classes are bad. The anti-class solutions still end up doing the same thing.
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
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.
Is it okay to return Object.create(this) inside the init function so that you can just say cat.init("djskdjajha")?
Short question: What's your opinion on the new class syntax in ES2015? My own is not too favorable, for some of the reasons you lay out in this video as reasons to prefer Object.create() to the 'new' syntax. It obscures what you're actually looking at, an object with a prototype, by making it look like an OOP class.
I basically have the same opinion. But it's a hell of a lot better than "new".
How so? The ES2015 class syntax doesn't replace 'new' after all.
It does somewhat replace the Object.create(proto).init(props) flow you demonstrated (which is a nice and clear flow, BTW), but using a sugar for the old -function StuffClass() {...}; Object.setPrototypeOf(StuffClass, proto); new StuffClass(props);- (LOLwrong) flow.
EDIT: I was thinking of this flow:
function StuffClass() {}
StuffClass.prototype = proto;
new StuffClass(props);
Ah, sorry for being implicit. I mean new as in "applying new to functions with a prototype property".
Btw, Object.setPrototypeOf(StuffClass, proto); is not the same as StuffClass.prototype = proto.
Right. True. This further adds to the confusion. >.<
The class syntax doesn't seem much of a step up, though. Doesn't much solve the fundamental problem of obscuring what happens.
Where found object with money?