3 ms·
Just because Crockford suggests it, doesn't make it a good idea. Manufacturing objects with a factory function, avoiding the "prototypal" part of JavaScript, i
by jashkenas 16y ago
Just because Crockford suggests it, doesn't make it a good idea.
Manufacturing objects with a factory function, avoiding the "prototypal" part of JavaScript, is slow, wastes memory, and prevents you from using "instanceof" to compare objects.
The point of a prototype is to share common functions and properties that don't change among instances. With "MySubclass", you manufacture a new copy of every function in the class, each time you create a new instance, with all of the closure-related overhead that entails.
Last time I benchmarked it, comparing a simple class with ten methods, in both prototypal style, and factory style, in Chrome:
Empty page, no objects: 0.9 MB
1 mil constructor objects: Brief pause, 32.4 MB
1 mil factory objects: About a minute pause, 368.1 MB
That said, if you know you're only going to have a dozen instances of the object on the page, then it hardly matters.
- praptak 16y ago"Just because Crockford suggests it, doesn't make it a good idea." On top of that Crockford does not actually state that closure-based objects should be preferred to prototypal inheritance. See: http://javascript.crockford.com/prototypal.html http://javascript.crockford.com/prototypal.html
- jashkenas 16y agoTo repeat myself: Just because Crockford suggests it, doesn't make it a good idea. Here's a set of benchmarks for creating a new instance, using the pattern you just linked to (called "Crockford Create" within): http://jsperf.com/object-create-vs-crockford-vs-jorge-vs-constructor/9 http://jsperf.com/object-create-vs-crockford-vs-jorge-vs-con... In Safari, it's about 5X slower than using a regular constructor function. In Chrome, it's about 20X slower. In JS, just using prototypes as Eich intended is the way to go.
- praptak 16y ago"To repeat myself: Just because Crockford suggests it, doesn't make it a good idea." I did not suggest anything like this. My point was that Crockford pretty much enumerates every sensible way to do inheritance in JS, with the conclusion quite similar to yours - Crockford suggests (in fact: describes) many things, so don't draw too much from this. Btw, he suggests the regular constructor too: http://javascript.crockford.com/inheritance.html http://javascript.crockford.com/inheritance.html
- demallien 16y agoI don't have the time to go looking for it, but he does in fact make precisely this claim in one of his video talks that I watched a few weeks back. Make of that what you will...
- demallien 16y agoLol, yup, you are of course spot on about the problems with factory functions - of course when you are using custom JS bindings, you can correct for this by pushing objects with many instances down into the native layer - which I had to do on the project I'm doing at the moment, precisely because it blew out the memory. I think that what we are looking at here is that there are two different use cases of Javascript that require two different strategies - if you want to produce subclasses of native objects, then you're going to be using factory functions, because no other solution exists in Javascript (well, at least not for JavascriptCore that I'm aware of). If you don't, then the use of a prototypal solution is more efficient.