Reputation: 13908
I just got Javascript: The Good Parts by Douglas Crockford and I'm having some difficulty understanding one of his examples regarding prototypes. The code in the book reads as follows:
if (typeof Object.create !== "function") {
Object.create = function(o) {
var F = function () {}
F.prototype = o;
return new F;
};
}
I'm assuming that this code is used to target a function's prototype. But why use such a complex approach? Why not just use variable
.prototype? Crockford is the leading expert on Javascript so I'm sure there is a good reason for using this model. Can anyone help me understand it better? Any help would be appreciated.
Upvotes: 6
Views: 329
Reputation: 827416
In ECMAScript 3, the new
operator was the only standard way to set the [[Prototype]]
internal property of an object, in this case, Crockford is just using a temporary constructor function F
for that purpose.
The o
argument of that method, is set as the prototype
property of the temporary constructor, and by invoking new F();
it builds a new empty object that inherits from F.prototype
(see this question for more details about how new
works).
For example:
var a = { a: 1 };
var b = Object.create(a); // b inherits from a
b.a; // 1
In the above example, we can say that the b
's internal [[Prototype]]
property points to a
.
Object.getPrototypeOf(b) === a; // true
In other words, b
inherits from a
.
With the same example, we could use an empty constructor, e.g.:
function F(){}
F.prototype = a;
var b = new F(); // b again inherits from a (F.prototype)
Remember also that the prototype
property of functions is different than the [[Prototype]]
property that all objects have, the prototype
property of functions is used when they are called with the new operator, to build a new object that inherits from that property.
Also, be aware that now, the ECMAScript 5 Standard is being implemented, and this shim, doesn't conform 100% with the spec, in fact, there are some features of the standard Object.create
method that cannot be emulated on ES3.
See also:
Upvotes: 5
Reputation: 88378
This code is for older JavaScript implementations that do not support Object.create
, which is specified in the ECMAScript 5 standard released in November 2009.
Many people say the preferred way to create an object is to specify a prototype for it at the time of creation. This can be called differential inheritance
or prototypal inheritance
. In fact, that is what Object.create
does:
var protoCircle = {x: 0, y: 0, radius: 1, color:"black"};
var myCircle = Object.create(protoCircle);
myCircle.x = 3;
myCircle.color = "green";
This make a green circle of radius 1 centered at (3,0).
The reason the code is so complex that before Object.create
was added to JavaScript, the only way to set an object's prototype was to create it with the new
operator. Objects created with new
got, as their prototype, the value of the constructor's prototype
property. It's definitely confusing, but the prototype
property is NOT the prototype of an object. Given a function object f
, f.prototype
is the object that will be assigned as the prototype of all objects constructed through new f()
. An object's real prototype is called [[prototype]]
or __proto__
but you cannot access these in standard ECMAScript. Confusing, eh?
As a side note. the ES5 specification has a more enhanced Object.prototype
specification than the one Crockford defined. It takes a second object for configuring properties of the object being defined.
Upvotes: 1
Reputation: 229361
var bar = Object.create(foo)
vs.
var bar = new Object()
the first bar
has foo
as its prototype; the second has Object
as its prototype.
Upvotes: 3
Reputation: 7096
This create method will instantiate a new object given the passed object as the prototype.
Upvotes: 0