delete keywords from its less-dynamic
predecessor languages. They feel a bit out of place in a garbage collected
language and are a source of confusion for newbies – one of the reasons
popular libraries such as jQuery, d3, and Ember.js have adopted APIs that
don’t require using
new at all. In this post I’ll show you one way do it,
delete are symmetric operators that combine memory
management and object lifecycle operations.
new allocates an instance and
calls the constructor, and
delete calls the destructor and deallocates it.
In garbage collected languages,
delete isn’t necessary; Java doesn’t have
and for a purpose (removing a property from an object) that’s not symmetric
delete plain objects.
new can itself be a source of confusion. Looking at instantiation with
new, it’s easy to see why:
new User() requires both a language keyword
and a unique syntactic form. In other scripting languages, neither are
needed: instantiation is done via regular function notation, either via a
class method as in Ruby (
User.new), or calling the class object as a
function as in Python (
new when calling a constructor can
produce some very strange behavior – leaving variables undefined and polluting
the global scope. John Resig gave a great rundown of the issues and proposed a solution, often dubbed the
1 2 3 4 5 6 7 8 9
Class constructors defined with the instanceof trick can be called with or
1 2 3 4 5
In either case, the result is a newly allocated and initialized User.
John Resig goes on to show how to create a reusable function that builds constructors that use the instanceof trick. This way, instead of writing it out manually for every class, you write it once and use a higher-level function to declare classes and their prototype properties:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
APIs that use the instanceof trick internally often publicly document only the
newless form of instantiation. This minimizes the API surface area, gives new
users less to learn, and avoids the awkward aspects of
advantage is that it allows the implementation to choose either the Module pattern or classic
prototypal instantiation without changing the public API. For example, we can
User class to use the Module pattern without changing how it’s
1 2 3 4 5 6 7 8 9 10
Similarly, if we had started out with the Module pattern, but discovered that we needed the memory efficiency of prototypal instantation, we could switch without changing client code.
An alternative that some library use is to pair each constructor with a factory
function of the same name but with leading lower-case, e.g.
1 2 3 4 5 6
This works, but again, it increases the size of the API you need to document and users need to learn, and unlike the instanceof trick, there’s no way to implement it in a reusable form. You’re stuck writing a factory wrapper for every class.
A newless API works great for as jQuery and d3, and I’ve found it very useful in iD as well. Consider using it for your next library.