Reputation: 2764
Maybe silly question to the JS gurus and ninjas out there but here goes:
My understanding of the prototype object/property of an object is that it is a blueprint for future instances of an object. Given this, shouldn't a newly created instance of an object be identical to the constructor object that created it?
var x = new Object();
console.log(x === Object.prototype); // returns false. why??
* UPDATE *
So understanding that this will return false because they are referencing different things, I still find that new Object() and Object.prototype
contain a different number of properties. So to refine my question: How do I correctly check the number of properties in a prototype Object; how do I iterate through them?
The reason I got confused by this is that if I create a simple constructor function:
function Circle(){
this.tail = "yes, has tail";
}
and want to get the number of properties it has, doing something like:
console.log(Object.getOwnPropertyNames(Circle.prototype));
// returns "constructor", I expected it to return "tail"
Upvotes: 0
Views: 478
Reputation: 120586
===
does not answer the question of whether two things are equivalent, but whether they are references to the same object.
x
and Object.prototype
in your example may have the same properties, so you can call them equivalent, but they are two different objects.
If you do
x.foo = 3
they are now no longer equivalent, because they were two different objects. You changed one but not the other.
If
x === Object.prototype
were true, then
x.foo === Object.prototype.foo
would be the same regardless of what you assign to x.foo
or Object.prototype.foo
.
EDIT:
function Circle(){ this.tail = "yes, has tail"; } console.log(Object.getOwnPropertyNames(Circle.prototype)); // returns "constructor", I expected it to return "tail"
There is no tail
property on Circle.prototype
because you have never done Circle.prototype.tail = ...;
. You define tail
only on Circle
instances via this.tail = ...;
.
I still find that
new Object()
andObject.prototype
contain a different number of properties.
You are also doing getOwnPropertyNames
. The own properties are those that are not inherited from the prototype, so by using that function on x
you are explicitly excluding all the properties of Object.prototype
.
The docs for hasOwnProperty
explain "own property" pretty well:
This method can be used to determine whether an object has the specified property as a direct property of that object; unlike the
in
operator, this method does not check down the object's prototype chain.
Upvotes: 2
Reputation: 123573
Regarding your update:
this
within a constructor function is the instance created with the new
keyword, not the prototype
.
So, in the case of your snippet...
function Circle(){
this.tail = "yes, has tail";
}
Setting this.tail
is similar to:
var c = new Circle();
c.tail = "yes, has tail";
tail
is only a property of the instance.
To set tail
on the prototype
, you must use:
Circle.prototype.tail = "yes, has tail";
Now, "Own" properties are those set directly on the instance. These counter and override prototype
properties of the same name:
function Circle() {
// give the instance its "own" `foo` property
this.foo = 'qux';
}
Circle.prototype.foo = 'foo';
Circle.prototype.bar = 'bar';
var c = new Circle();
console.log(c.foo); // the overridden "qux", not the inherited "foo"
console.log(c.bar); // "bar", as inherited
// yet the prototype still persists to have its "own" `foo`
console.log(Circle.prototype.foo); // "foo"
// While the instance has keys for all involved properties
console.log(Object.keys(c)); // [ "foo", "bar" ]
// It also retains which are its "own"
console.log(Object.getOwnPropertyNames(c)); // [ "foo" ]
Upvotes: 0
Reputation: 2940
x is an instance of "Object". You probably want to check if x has a Object as constructor. Prototype isn't constructor. Try this
var x = new Object();
console.log(x.constructor === Object);
Upvotes: 0
Reputation: 169551
console.log(Object.getPrototypeOf(x) === Object.prototype); // true
If you want to get the hidden property [[Prototype]]
that points to the next element in the prototype chain for an object just call Object.getPrototypeOf
.
Also you mis-understand how the prototype chain works.
For any given object, if you look up a property it will first look at that object. It will then (recursively) look at the objects [[Prototype]]
value for whether it has that property.
Example prototype chains :
var o = new Object();
// o -> Object.prototype -> null
var a = new Array();
// a -> Array.prototype -> Object.prototype -> null
var Super = function () {};
var Child = function () {};
Child.prototype = Object.create(Super.prototype);
var c = new Child();
// c -> Child.prototype -> Super.prototype -> Object.prototype -> null
Upvotes: 1