Skip to content

Comment on Stop Using Constructors in JS (2012)

Comments

"Stop writing prescriptive articles about software development when you're speaking from a position of ignorance"

There are many reasons to keep on using `new`, the biggest one is probably performance, `new Foo` will always outperform `Object.create(FooProto)`.

Really though, this kind of article just grinds my gears. There are so few absolutes in software development, articles like:

    "You should always X"
  

    "Stop doing Y"
almost always really mean
    "I don't actually understand X or Y"
the biggest one is probably performance, `new Foo` will always outperform `Object.create(FooProto)`.

He's right, `new` is more than 10x faster in Chrome and Firefox for me at least:

http://jsperf.com/create-new

Why would it `always outperform` though? Seems like an implementation detail. Object.create should be faster since it doesn't run a constructor.

The ever-wonderful Vyacheslav Egorov has a nice article on this:

http://mrale.ph/notes/constructor-vs-objectcreate.html

I bet this is because most of JS compilers are optimized in lower level for certain "popular" tasks, developers use to do.

`new Foo` will always outperform `Object.create(FooProto)`

If I create an interpreter that changes `new Foo` to `$new(Foo)` where $new is a JS function that uses Object.create to do what the `new` operator does in spec (e.g., treat it as syntactic sugar) then it's unlikely that `new Foo` would outperform `Object.create(FooProto)`. Just because the current interpreters are hyperfocusing on `new` doesn't mean they can't make `Object.create` faster in the future.

All requiring `new` does is add an implicit requirement that the name of your function is actually `new X` instead of `X` with the added requirement that all aliases of the function be prefixed with `new `, which is not composable.

Yeah, `new` might be faster than not using it right now, but that's a bug in the interpreters. And for a lot of objects, your inner loop is not going to be in creation.

Probably the problem with your perspective is that you're still thinking about JS "interpreters", when we don't generally have those any more - we have JITs that compile JS to machine code.

`new Foo()` is faster because it can be compiled to more efficient code today and probably always will be. Your argument is a bit like the "given a sufficiently intelligent compiler" one, I don't care about what JS engines of the future might do, I care about my code's performance today.

I find it odd that you rail against absolutes and then immediately turn around and defend your own.

If you meant that new is faster today, say so. That's not the same as "will always outperform".

I said there are few absolutes, not that there are no absolutes :)

`new Foo` has simpler semantics than `Object.create(FooProto)` and therefore I believe it will always be faster. That performance gap can of course narrow, but I think `new` will always be the fastest. Happy to be proved wrong.

Every time I hear how using 'new is bad' (or "considered harmful") in Java or Javascript it just makes me chuckle. Refactoring is not hard with half-decent toolchain so adding extra complexity/indirection doesn't improve anything.

In most languages, I would agree with you. Unfortunately, I haven't encountered a "half-decent toolchain" in JavaScript – or at least a toolchain that would help me reliably and fearlessly refactor big bases of code.

Performance isn't really a big concern unless you're creating several hundreds of thousands of new objects per second. And I would question why you need to do that in the first place...

Perhaps he should've taken the "Constructors considered harmful" approach?

Another point against advice like this is that you're going to be forced to use the supposedly "bad" technique when you interact with the rest of the world.

For instance, if you want to use any of Google's Javascript libraries like their map api client, you're going to be using "new". So, now you've done a bunch of work to avoid using "new" but as soon as you step outside of your bubble, you're going to have to find a way to deal with "new" anyway. So, what's the point? Just use a good linter and be done with it.

Yeah, and you also have to use Google's ugly name spacing and global scope pollution instead of modern (sane) module approaches like CommonJS.

Following an old-school technique just because you might see it in some legacy code doesn't seem like a great argument.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.