To answer your "To begin with...", you might still run into Javascript environments where
console.log(typeof Object.create);
will report
undefined
or some such (assuming you even have a console object with a log function available.) The reason for that outer if (typeof Object.create !== 'function')
wrapper is to only define this in the case that your JS environment doesn't already do so. There are many older browsers and other environments where your code might one day run that could conceivably not have Object.create
defined.
Now as to how this actual function works, its based on how JS handles objects. Objects are simply collections of named properties, or more properly associations between String names and property values. But many also have a special property, which is their prototype
. This is simply a pointer to another object. That object can also have its own prototype
object, and so on. Eventually, though, the prototype chain dies out when the prototype
of one of these objects is null. These prototype objects also are collections of named properties, and when the Javascript engine is searching your object for a named property, if it doesn't find it directly on your object, it checks to see if your object's prototype might contain it, and if not, if the prototype of that object might contain it, and so on, until the chain dies out.
The point of these prototype objects is that they can be shared. Several objects, or even several million objects, can share a single prototype. This is substantially different from how class-based inheritance schemes work, but it can often be put to a similar purpose. You can define a single copy of a function, and all objects created from a common constructor function will use that one copy. Before such techniques as Object.create
were created, this was the only real means of doing Object-oriented programming in Javascript.
Crockford's code is using that older technique to simulate part of what the newer technique is supposed to do. Object.create
defines some behaviors that can't really be achieved through the older mechanisms, but the most basic behaviors are simply to create a new object whose prototype is the specified object. That's exactly what the older technique, using F.prototype = o; return new F();
accomplished. So this code is pretty much the standard way to shim the new behavior into older environments. For another example of this, see the MDN create page