views:

662

answers:

6

I think its a 5am brain drain, but I'm having trouble with understanding this.

obj = ['a','b'];
alert( obj.prototype ); //returns "undefined"

Why isn't obj.prototype returning function Array(){ } as the prototype? It does reference Array as the constructor.

A: 

Not really my cup of tea, but does this way of defining it make "obj" an array? Tried

obj = new Array();
obj[0] = "a";
obj[1] = "b";

?

mike nvck
Tried that too, same thing as the array literal
Geuis
An array literal is just a more convenient way of creating an array: https://developer.mozilla.org/en/A_re-introduction_to_JavaScript#Arrays
Simon Lieschke
+6  A: 

Because the instance doesn't have a prototype, the class* does.

Possibly you want obj.constructor.prototype or alternatively obj.constructor==Array

* to be more accurate, the constructor has the prototype, but of course in JS functions = classes = constructors

annakata
Nah, that isn't it either. alert( obj.constructor.prototype ); returns nothing.
Geuis
no, it returns the prototype.toString() - notice how this isn't null, and is not the same thing as returnign nothing - that is the correct reference, what you're doing with it may not be
annakata
Ok, so I think I'm understanding. So obj = 'a', obj = {a:'a'}, obj = ['a'], obj = 0 have no prototypes because they are instances.But, obj = function(){} returns "[object Object]" for its prototype
Geuis
because function is a constructor so it has a prototype - functions are basically the only things you'll get a prototype reference on, whether those are native functions or your own
annakata
long story short - functions are special in JS :D
annakata
So I'm wondering why this doesn't work: obj = function(){ return 'obj'; } obj2 = new obj(); alert( obj2() ); //says obj2 is not a function
Geuis
obj2 is a new instance of the class type obj which in this case is essentially an empty object *not* a function (the return is irrelevant in this usage). If you wrote obj.prototype.foo = function(){return "foo";} then you could create obj2 as a new obj and call obj2.foo(), but not obj.foo();
annakata
+1  A: 

I'm not sure you can access the prototype object from an instance of an object. The following behaviour might help you:

alert(Array); // displays "function Array() { [native code] }"
alert(Array.prototype); // displays ""
alert(['a','b'].constructor); // displays "function Array() { [native code] }"

obj.prototype isn't returning function Array() { ... } as that is the object's constructor.

Simon Lieschke
‘constructor’ isn't really reliable; it's not present on IE, and has a subtly different behaviour to what it looks like it's doing, which breaks many forms of subclassing. Best avoided if possible!
bobince
A: 

what does

alert(typeof obj.prototype)

return?

Russ Cam
It returns 'undefined'.
Geuis
That will return undefined because the type of an undefined object will always be undefined :)
Simon Lieschke
@simon - apologies, your're right :) annakata is on the right lines
Russ Cam
+1  A: 

In your example, obj is an instance of an Array, not the class Array itself.

Another way to understand it is that for example, you can't inherit from an instance of an object (or class), you can only inherit from the object (or class) itself, which in your example it means that you could inherit from the Array object, but not from a direct instance of the Array object such as obj.

Sergi
Thanks. I tested the idea against other object types and also got the 'undefined' response, so I'm understanding that. The only one that is different is the case of: obj = function(){}This returns [object Object]
Geuis
A: 

According to the ECMA spec, an object's prototype link isn't visible, but most modern browsers (firefox, safari, chrome) let you see it via the __proto__ property, so try:

obj = ['a','b'];
alert( obj.__proto__ );

An object also has the `constructor' property set on construction, so you can try:

obj = ['a','b'];
alert( obj.constructor.prototype );

However, obj.constructor can be changed after an object's contruction, as can obj.constructor.prototype, without changing the actual prototype pointer of obj.

Andrey Fedorov