google.maps.Map is the constructor function for map objects in version 3 of the Google Maps JavaScript API. Because JavaScript is a very flexible and accommodating language, it should be easy to extend the Map object and roll your own mapping platform.

Unfortunately, the design of google.maps.Map makes the usual way of extending an object in JavaScript unworkable:

As it turns out, Google’s map constructor requires a DIV element argument. It’s tempting to do this instead:

Well, it does work. But if you step through the constructor function you’ll see it devotes a lot of time and energy to decorating a map object that will never see the light of day. Our objective in creating the prototype object is for it to be an instance of google.maps.Map, extending its prototype chain to MyMap. But it has no other use, so we’d prefer that the constructor return immediately if no arguments are provided.

But, it doesn’t. And as it turns out, our best efforts to ignore the DIV requirement fall short. When the constructor throws an error, the prototype binding fails:

Here’s another approach which, at first, seems to do the trick:

Because our MyMap object is an instance of google.maps.Map, it inherits all of the properties of the objects in the prototype chain. However, this approach has a subtle flaw:

By copying the properties of google.maps.Map into MyMap, we also copied the prototype. With both constructors sharing the same prototype, they are like Siamese twins in the prototype ancestry. They share all of their properties and it defeats the purpose of adaptation by inheritance.

We might try copying the prototype’s properties instead of the prototype itself…

… but then the MyMap prototype is disinherited. MyMap objects would appear to have the same methods as google.maps.Map objects, but any calls in those methods to supertype methods would fail to resolve.

The approach I’ve settled on (for now) is to wrap google.maps.Map like this:

It provides exactly the same behavior when arguments are provided, but won’t complain if all we want is a prototype object.