Why can't I access the 'x' property from A?
A = {}; B = {y: 'y'}; C = {x: 'x'}; A.prototype = B; B.prototype = C; A.x
The prototype of an object is not reflected by the prototype
property (confusing though that may be). In fact, there is no standard, direct way of setting the prototype of an object after you've created it (and it's only very recently that there's been any standard way to retrieve an object's prototype). In the code you've quoted, all you've done is create a normal property called prototype
on the objects; it may as well have been called foo
. :-)
There is a special prototype
property in JavaScript, but it's on functions: It's the object that will be assigned as the prototype of the objects created by that function if you use it with the new
keyword (e.g., as a constructor function). In fact, until very recently the only way to assign a prototype to an object was through a constructor function:
function makeA() {
}
makeA.prototype.x = "foo";
A = new makeA();
alert(A.x); // alerts "foo"
...and that's still the only widely-supported means of doing it.
Things are changing slightly with the new ECMAScript 5th edition specification, but you can still only set the prototype of an object when you create it, not after the fact. What the new stuff does is make it possible to do it directly rather than by making a constructor function to do it. This is the new Object.create
feature in Section 15.2.3.5, but it's not widely supported yet. (There are several other nifty features of the 5th edition, including the ability to get the prototype of an object via Object.getPrototypeOf
; but still no way to change it after the fact.)
There is a non-standard property that some implementations (like Firefox's SpiderMonkey engine) provide, __proto__
, but it's not supported broadly and was not included in the latest specification.
Using the new Object.create
, you could do what you want like this:
var C = {x: 'x'};
var B = Object.create(C);
B.y = 'y';
var A = Object.create(B);
alert(A.x); // alerts "x"
...but since Object.create
is so new, you'll find that in most implementations, you need to create it because it's not there. That's easy enough if we ignore its second argument (which can only be partially emulated):
if (!Object.create) {
// An *incomplete* emulation of Object.create, doesn't support the optional
// second parameter defined by the spec.
Object.create = function(proto) {
var obj;
// There's no point in calling this with a null or otherwise "falsy"
// prototype, but let's handle it if you do
if (!proto) {
return {}; // Just a generic object
}
// Define a constructor object that uses
// the prototype
function ctor() {
}
ctor.prototype = proto;
// Create and return the object
return new ctor();
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With