-
-
Save petermichaux/2552304 to your computer and use it in GitHub Desktop.
var todoViews = todoModels.map(function(todoModel) { | |
return new TodoView(todoModel); | |
}); | |
// if Function.prototype.new is defined or TodoView.new is defined using "this" | |
var todoViews = todoModels.map(TodoView.new, TodoView); | |
// if Todo.new is defined without using "this" | |
var todoViews = todoModels.map(TodoView.new); | |
It's also crazy optimized in v8 (and, I imagine, other implementations as well.)
Using a shim in place of Object.create
(which is everything but crazy optimized at this point) you are basically still using constructors, just with one additional function call. Most code-bases can handle that :)
why bother using a class at all?
Good question. Sometimes a function returning an "ad hoc object" is the right solution. However, if there are more than one instance I do like the fact that function objects are inherited, not duplicated, and "classes" (just objects in my case) lend themselves better to extension. I think we agree in most practical senses except for how to define these "classes".
My dream solution would be if ES6 introduced classes that don't rely on keywords (like new
) and removed constructors. But that's not gonna happen, so with ES6 (if it ever materialises) we'll have yet another way of creating objects. :(
I've occasionally done that instanceof "trick", but it's quite easy to forget and I've decided that if you forget your "new" (provided that you even use it for inheritance), then it's your problem.
@isaacs The reason I like this approach is that even though it's hacky in one spot, it's generally less hacky everywhere else."
This is what I've observed too... put a hack in there, less hacks elsewhere. :P
@cjohansen To back up @isaacs claim on the performance: http://jsperf.com/object-creation-access/2
I do feel the simplicity of a more direct mapping between the delegative prototypical OO model and the primitives used, which in this case would amount to using Object.create + some abstractions on top of it, to lead to code that is easier to follow as well. In which case, I don't really care about the performance differences between constructors and the other means of creating objects — that is, of course, unless you need to create millions of objects per second, but then you'll be fighting the GC anyways.
Object.create
unfortunately is magnitudes slower than new
in some engines. It's rather an engines (not specification) issue, so hopefully it'll get better. Anyway for now I would use Object.create
only for prototype extensions (e.g. Animal to Dog), and stick to new
when creating object instances (e.g. Dog to sparky).
FTR: I'm aware of the issues with Object.create
, and a simple solution is to use a constructor-based shim (ignore the descriptor argument). I don't think a poorly performing native Object.create
is a good argument against basing a design on just objects and Object.create
-like construction.
@cjohansen I had noticeable issues on V8 engine (which implements Object.create
natively), what would you propose in that case? Also it's not that better for shims, see: http://jsperf.com/object-create-vs-crockford-vs-jorge-vs-constructor/31
It's not great argument but sometimes poor performance asks for refactoring back to new
(I've gone that path in one of the projects).
@medikoo On Firefox, Object.create comes out the fastest. V8 obviously has some insane optimization for the bare constructor use (as mentioned before). I don't really worry about it...
@cjohansen on Firefox performance of Object.create vs new is not really different (it's slightly faster on benchmark that's it), on V8 it is noticeable in real world. Hopefully one day V8 will have it fixed. I also do not tend to worry about things prematurely ;)
Yep. No one said that JavaScript was the prettiest language :) The reason I like this approach is that even though it's hacky in one spot, it's generally less hacky everywhere else. If you're not creating bunches of these things, then why bother using a class at all?
Well, it's just a standard and convenient way to do "set up this object" logic, which is sometimes nice. It's also crazy optimized in v8 (and, I imagine, other implementations as well.)