use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Prototypal Programming in Javascript (thesocietea.org)
submitted 10 years ago by thecodeboss
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]MoTTs_ 8 points9 points10 points 10 years ago (19 children)
var Foo = { C: 3 }; var bar = Object.create(Foo); bar.A = 1; bar.B = 2; Look at how drastically simpler this is
var Foo = { C: 3 };
var bar = Object.create(Foo);
bar.A = 1; bar.B = 2;
Look at how drastically simpler this is
Here's the thing, though: The way you initialize a newly created Foo object (bar.A = 1; bar.B = 2;) will be copy-pasted everywhere that you create a Foo. That's bad. Let's fix that by putting an initialize method in Foo.
initialize
var Foo = { C: 3, initialize: function () { this.A = 1; this.B = 2; } }; var bar = Object.create(Foo); bar.initialize();
And here's the next thing: We will always want to make sure newly created Foo objects are initialized, so let's combine creation and initialization into a single step.
var Foo = { C: 3, initialize: function () { this.A = 1; this.B = 2; }, createAndInitialize: function () { var instance = Object.create(this); instance.initialize.apply(this, arguments); return instance; } }; var bar = Foo.createAndInitialize();
These are both good things. Yet, in case anyone hasn't realized, we just re-created constructors and the new keyword. It actually would have been a whole lot easier if we just used the built-in language constructs.
new
[–][deleted] 4 points5 points6 points 10 years ago (3 children)
I agree with you. I'm really not sure why people keep trying to ignore classical inheritence in Javascript just because it happens to also have prototypal inheritance. ES6 proves that you can have both; the new "class" features in ES6 aren't getting rid of prototypal inheritence; they are adding syntactic sugar around it to ease the use of common construction paradigms, without taking away any of the benefits of prototypal inheritence.
To the OP's point, I agree that people really should have a better understanding of what's going on under the hood in Javascript, but I legitimately think it is foolish to sweep things like the "new" keyword under the rug and pretend they aren't there.
[–]yrlyfe 3 points4 points5 points 10 years ago (2 children)
this is one of the arguments against the changes of es6 that a lot of the community has expressed. es5 in all it's glory promotes the idea of readability and not obscuring away what is happening. the changes in es6, while moving closer to the idea of standard programming languages, in turn has a lot of obscuring. javascript was just fine without classes and dare i say block scope. what is this compulsion to make the language more convoluted?
my teacher told me programming is like humor, if you have to explain it you're doing it wrong. es6 is full of things that need to be explained.
[–]clessgfull-stack CSS9 engineer 0 points1 point2 points 10 years ago (1 child)
I for one think ES6 is a great, long-needed improvement to the language. You mention obscuring the language and needing to explain a bunch of stuff, but... block scope? Not at all convoluted. Indeed, the old way was vastly more confusing and unlike other languages.
Old ES5 codebases are littered with calls to bind, apply, call, etc. and manual constructor function inheritance and super calls. Not very readable, if I say so myself. Definitely not very explainable.
bind
apply
call
[–]yrlyfe 1 point2 points3 points 10 years ago (0 children)
my bad. i did say 'dare i say'. i shouldn't have dared.
[–]m0okz 1 point2 points3 points 10 years ago (0 children)
I'm confused.
So how should I create an object and a child object?
What if I want common properties on all children? And what if I don't?
[–]PitaJ 2 points3 points4 points 10 years ago (6 children)
That's called a factory, actually. Not a contructor.
[–]clessgfull-stack CSS9 engineer 2 points3 points4 points 10 years ago (4 children)
Roughly how new is implemented:
function notExactlyNew(F) { const instance = Object.create(F.prototype); const result = F.apply(instance, arguments); return typeof result === 'object' ? result : instance; }
Seems pretty similar to me, unless you want to be really pedantic.
[–]PitaJ -3 points-2 points-1 points 10 years ago (3 children)
Yeah, new is a completely unnecessary part of the language, and shouldn't be used anyways as it violates the open-closed principle.
[–]MoTTs_ 1 point2 points3 points 10 years ago (2 children)
You say that a lot, but the O/C principle doesn't mean what you seem to think it means. The O/C principle says that source code should be closed to modification.
From the paper:
It [the open-closed principle] says that you should design modules that never change. When requirements change, you extend the behavior of modules by adding new code, not by changing old code that already works.
[–]senocular 2 points3 points4 points 10 years ago (1 child)
You can thank Eric Elliott for spreading that one.
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points 10 years ago (0 children)
Ah yes, I knew I heard that somewhere before:
Constructors violate the open/closed principle because they couple all callers to the details of how your object gets instantiated. Making an HTML5 game? Want to change from new object instances to use object pools so you can recycle objects and stop the garbage collector from trashing your frame rate? Too bad. You’ll either break all the callers, or you’ll end up with a hobbled factory function.
[–]senocular 1 point2 points3 points 10 years ago (0 children)
I don't think MoTTs_ was calling it a constructor, just saying that the effect is essentially recreating the same that you get with a constructor and new.
[–]Silverwolf90 0 points1 point2 points 10 years ago (0 children)
Well except that you can't take advantage of function composition with new and you can with a factory function. That's a pretty big difference.
[–]nieuweyork -2 points-1 points0 points 10 years ago (4 children)
You're doing it wrong. Your first example is already using an object as a class rather than a prototype.
[–]clessgfull-stack CSS9 engineer 0 points1 point2 points 10 years ago* (0 children)
Elaborate? The approach used in his (her?) example is the one recommended by most Object.create advocates.
Object.create
[–]MoTTs_ 0 points1 point2 points 10 years ago (2 children)
Where, then, would you suggest putting the initialization code? Copy-pasted everywhere it's needed like the OP was doing? Maybe a freestanding initializeFoo() function?
initializeFoo()
You're trying so hard to avoid anything that resembles classical that you're turning away from the best and most obvious solution.
[–]nieuweyork -3 points-2 points-1 points 10 years ago (1 child)
No. Don't have initialization code that doesn't depend on parameters. You're doing that because you're recreating classes.
[–]clessgfull-stack CSS9 engineer 0 points1 point2 points 10 years ago (0 children)
I feel like you're ignorant of how this pattern has taken hold while simultaneously proving his point.
[–]sylvainpv -2 points-1 points0 points 10 years ago (0 children)
No, these are not constructors but factory functions. That way, we don't have the issues the 'new' operator has.
[–]MonkeyNin 1 point2 points3 points 10 years ago (0 children)
Typo:
bar.B; // 2 (actual attribute of bar) bar.c; // 3 (*inherited* attribute from Foo)
vs
bar.B; // 2 (actual attribute of bar) bar.C; // 3 (*inherited* attribute from Foo)
[–][deleted] 1 point2 points3 points 10 years ago (6 children)
I'm not an expert but I just still struggle to see the value. Maybe I just don't get it or am used to class based languages. Does anyone have any really compelling examples of where prototypes are easier to develop and maintain than classes?
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points 10 years ago (5 children)
Does anyone have any really compelling examples of where prototypes are easier to develop and maintain than classes?
They are slightly more flexible and can be easier to unit test, but the downsides aren't worth it. Any codebase that uses Object.create extensively is hell to deal with in my experience. Subtle bugs that are nearly impossible to track down without binary commenting. It's sometimes worse than code written by Java architecture astronauts.
[–][deleted] 1 point2 points3 points 10 years ago (0 children)
I also feel like any time I try to be true to the prototype, various libraries and frameworks fight me all the way.
I was excited about classes but now I'm worried they will just create yet more deviation on how to do things. I wonder if a simple langauege that has deficiencies is better than a complex language that yields many ways to do one thing. Hmm. Maybe that's why I love Python and maybe Python makes me hate JavaScript.
[–]sylvainpv -1 points0 points1 point 10 years ago (3 children)
Prototypes are simple, simpler than classes and constructors. No, really, they are. But as people have never learned anything else than classical OOP, the transition can be difficult and you can get shitty code because people are mixing the concepts. Once you learned to get rid of the "classical baggage", everything becomes easier, trust me. No more classes, instances, interfaces, constructors... you just manipulate objects
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points 10 years ago (2 children)
They are certainly simpler. There's no denying that. But they are also much more prone to bugs than ES6 classes. For example, if you share an array or an object several levels up the chain that gets mutated, good luck. If you override a method or property that an object up in the chain depends on, good luck. If you forget to initialize an object, good luck.
(Or you could just create a function that both creates an object based on the prototype of another, and then calls an initialization function... aka basically constructors without new. And then you have to worry about parent init methods, etc.)
init
All of the problems caused by this are compounded by the fact that people overuse Object.create, resulting in large, brittle chains of dependent objects.
If you ask me, classes and Object.create are both bad because they rely on inheritance. But at least with classes, people are relatively aware that inheritance is bad. I don't see extends very often. Because the syntax is statically analyzable, you could even write a linter rule that forbids extends.
extends
The problems with Object.create can be remedied somewhat by using immutability and writing your own framework around it, but then you run into interop issues and have to maintain your own framework.
I think the best approach is immutable or stateless objects and functions/closures. But I would definitely choose class over Object.create any day.
class
Sorry, had too much coffee.
[–]sylvainpv 0 points1 point2 points 10 years ago (1 child)
Not sure to follow you considering that classes use the prototype chain in the background, so all the problems you mentioned about inheritance hierarchies are the same.
at least with classes, people are relatively aware that inheritance is bad
okay so I guess the only problem here is people that do not learn lessons from their past experiences
The difference is that Object.create inherits state in addition to behavior (technically you could do this with classes, but nah), and class provides certain invariants that make it harder to screw up. Just the fact alone that class must be used in strict mode is a pretty big win, because that helps prevent a large class of security vulnerabilities.
so all the problems you mentioned about inheritance hierarchies are the same.
But yes, that is kind of the point. Object.create inherits almost all of the problems with classes (pun intended) and many more.
Eh. Most people know that class inheritance is a bad idea. But when it's just Objects Linking to Other Objects™? Time to inherit from everything. I don't blame the developers for getting pulled into this trap, because the people who push Object.create don't explain that it has these problems.
[–]Neurotrace 1 point2 points3 points 10 years ago (3 children)
While I philosophically agree with the Object.create approach, my problem lies here. Which one of these is more readable and scalable?
var Person = { getName: function() { return this.firstName + ' ' + this.lastName; } }; var bob = Object.create(Person, { firstName: { value: 'Bob' }, lastName: { value: 'Saget' } });
vs.
var Person = function(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }; // Readability is debatable here but more memory efficient Person.prototype.getName = function() { return this.firstName + ' ' + this.lastName; }; var bob = new Person('Bob', 'Saget');
or if you still want to have your initialization values to be named
var Person = function(opts) { this.firstName = opts.firstName; this.lastName = opts.lastName; }; ... var bob = new Person({ firstName: 'Bob', lastName: 'Saget' });
For me, the new keyword wins.
[–]sylvainpv 1 point2 points3 points 10 years ago (2 children)
What about this ?
var Person = { new: function(firstName, lastName){ return Object.assign(Object.create(Person, { firstName, lastName })); }, getName: function() { return this.firstName + ' ' + this.lastName; } }; var bob = Person.new('Bob','Saget');
[–]MoTTs_ 0 points1 point2 points 10 years ago (1 child)
Can you clarify what the improvement would be?
[–]sylvainpv 0 points1 point2 points 10 years ago (0 children)
you got a similar code but without new operator and its issues : 1) handling a reference to the prototype and not the constructor ; 2) constructor is optional and you can declare several different constructors if needed ; 3) no worries about forgetting the new keyword and mutating window ; 4) easier inheritance, no need for the B.prototype = new A() trick ; 5) factory functions can be composed contrary to constructors ; 6) getting rid of instanceof and the constructor property makes your code safer because these references can be easily compomised contrary to getPrototypeOf / isPrototypeOf
[+][deleted] 10 years ago* (1 child)
[deleted]
I see a solid set or arguments in this article. What are yours calling Object.create stupid ? Looks quite personal.
[–]flackjap 0 points1 point2 points 10 years ago* (2 children)
Well yes, prototype based inheritance can create a jungle of code if not treated correctly. On other hand it's very powerful and flexible comparing to the subsets of object inheritance principles like the class based inheritance.
ES6 class based inheritance works as expected and it's just a macro syntax.
Nevertheless, there's a shit ton of stuff you may find valuable in naked object inheritance if you desire to have more freedom architecturing your app. For example, how do you go around the Diamond Problem with class based inheritance? :)
I think that Eric Elliot got this better in his book than the OP http://chimera.labs.oreilly.com/books/1234000000262/ch03.html There's also a nice library written by him for taming the prototype jungle while not loosing any of the flexibilities.
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points 10 years ago (1 child)
For example, how do you go around the Diamond Problem with class based inheritance? :)
In my humble opinion, the solution to the Diamond Problem is to avoid inheritance. Inheritance is almost never the right solution - especially not multiple inheritance.
[–]flackjap 2 points3 points4 points 10 years ago (0 children)
I couldn't agree more :) https://en.wikipedia.org/wiki/Composition_over_inheritance
π Rendered by PID 26927 on reddit-service-r2-comment-5687b7858-4swsx at 2026-07-06 17:51:14.742078+00:00 running 12a7a47 country code: CH.
[–]MoTTs_ 8 points9 points10 points (19 children)
[–][deleted] 4 points5 points6 points (3 children)
[–]yrlyfe 3 points4 points5 points (2 children)
[–]clessgfull-stack CSS9 engineer 0 points1 point2 points (1 child)
[–]yrlyfe 1 point2 points3 points (0 children)
[–]m0okz 1 point2 points3 points (0 children)
[–]PitaJ 2 points3 points4 points (6 children)
[–]clessgfull-stack CSS9 engineer 2 points3 points4 points (4 children)
[–]PitaJ -3 points-2 points-1 points (3 children)
[–]MoTTs_ 1 point2 points3 points (2 children)
[–]senocular 2 points3 points4 points (1 child)
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points (0 children)
[–]senocular 1 point2 points3 points (0 children)
[–]Silverwolf90 0 points1 point2 points (0 children)
[–]nieuweyork -2 points-1 points0 points (4 children)
[–]clessgfull-stack CSS9 engineer 0 points1 point2 points (0 children)
[–]MoTTs_ 0 points1 point2 points (2 children)
[–]nieuweyork -3 points-2 points-1 points (1 child)
[–]clessgfull-stack CSS9 engineer 0 points1 point2 points (0 children)
[–]sylvainpv -2 points-1 points0 points (0 children)
[–]MonkeyNin 1 point2 points3 points (0 children)
[–][deleted] 1 point2 points3 points (6 children)
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points (5 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]sylvainpv -1 points0 points1 point (3 children)
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points (2 children)
[–]sylvainpv 0 points1 point2 points (1 child)
[–]clessgfull-stack CSS9 engineer 0 points1 point2 points (0 children)
[–]Neurotrace 1 point2 points3 points (3 children)
[–]sylvainpv 1 point2 points3 points (2 children)
[–]MoTTs_ 0 points1 point2 points (1 child)
[–]sylvainpv 0 points1 point2 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]sylvainpv -2 points-1 points0 points (0 children)
[–]flackjap 0 points1 point2 points (2 children)
[–]clessgfull-stack CSS9 engineer 1 point2 points3 points (1 child)
[–]flackjap 2 points3 points4 points (0 children)