1

I am really fixed with JS object related concepts. For ex: Crockford says: Objects produced from object literals are linked to Object.prototype

Now on console when I type:

// input represented with >

> var a = {};
> console.log(Object.getPrototypeOf(a));
Object {} // <-- output
> console.log(a.prototype);
undefined

Crockford says:Function objects are linked to Function.prototype (which is itself linked to Object.prototype)

> function b(){};
> console.log(Object.getPrototypeOf(b));
function()
> console.log(b.prototype);
b{}
> console.log(b.prototype.prototype);
undefined
> console.log(Object.getPrototypeOf(b.prototype));
Object {}

When I do getPrototypeOf() I get the expected output, but when I try to use the prototype property I get undefined. Cant figure out the reason.

Also for line 5 return value is function(). Can some please explain does this say ? I expected an Object to be returned.

It would be great if someone please give me insight/good links/some class diagrams(as we have in java) to follow for understanding prototypal inheritance.

theonlygusti
  • 11,032
  • 11
  • 64
  • 119
JackSparrow
  • 187
  • 1
  • 2
  • 15
  • 3
    Ordinary objects don't have a `prototype` property; that's why `Object.getPrototypeOf()` exists. – Pointy Jan 07 '15 at 16:18
  • 4
    Also be aware that the browser console is not meant to be a vehicle for exploring JavaScript semantics; it's a tool meant to be useful to web developers for debugging etc. The console displays values in ways that are not always accurate with respect to language semantics. – Pointy Jan 07 '15 at 16:20
  • Thanks @Pointy for the suggestion...can you suggest some links..I really wana fix this stuff once in for all (like u have things very crystal clear in java when coming to objects)...also adding to the response ....I am unable to access 'prototype' property but by using getPrototypeOf() I am able to get access of 'prototype' . Does that mean 'prototype' property is made private (may be by making use of closures) and is only accessible using a getter method – JackSparrow Jan 07 '15 at 16:31
  • There is simply no "prototype" property on ordinary objects. Function objects have a "prototype" property, but not other objects. A search for "JavaScript inheritance tutorial" turns up **lots** of hits. Also the ["You Don't Know JS"](https://github.com/getify/You-Dont-Know-JS) series by my friend Kyle Simpson is available online and for purchase, and it includes coverage of inheritance. – Pointy Jan 07 '15 at 16:38
  • 1
    The Prototype you are talking about is different from that of `prototype` property you are printing. Refer [this](http://stackoverflow.com/a/9959753/1261124) great little answer, for a similar question! – jjk_charles Jan 07 '15 at 16:41
  • objects to have a `__proto__` property, which is probably what you want. it's frowned upon to use though, but it's almost always the same as obj.constructor.prototype. – dandavis Jan 07 '15 at 16:47
  • I suggest to check this link...absolutely wonderful http://stackoverflow.com/questions/650764/how-does-proto-differ-from-constructor-prototype – JackSparrow Jan 07 '15 at 17:51

1 Answers1

0

Okay. Here's the thing. There are some concepts in JS that seem really convoluted at the start, but are actually really straightforward. Let's have a look at a few of them.

1) function.prototype property

When you define a function, the JS engine creates an anonymous object and binds the two using property names prototype and constructor as follows:

function foo(){}

/* Performed by JS engine internally */
// foo.prototype = {};
// foo.prototype.constructor = foo;

Therefore, only functions have .prototype.

The .prototype is used only and only when the function is invoked using the new operator.

2) References

In JS, references can be used to pass along a variable, without creating a duplicate of it. Perhaps an example might help here:

var a = 1;

var b = { val: 1 };

var c = { val: 1 };

var x;

/*variable cloned*/
x = a;
x++;
console.log(a); // 1
console.log(x); // 2

/*variable refernced*/
x = b;
x.val++;
console.log(b); // { val: 2 }
console.log(x); // { val: 2 }

/*variable cloned*/
x = c.val;
x++;
console.log(c); // { val: 1 }
console.log(x); // 2

3) object.__proto__ property

Any object created by invoking a function with the new keyword, like var x = new foo();, will have a __proto__ property on it that is the object referenced by its constructor function's .prototype property. Re-assigning foo.prototype to somethings else will not affect objects that have already been created.

In other words,

function foo(){}
// foo.prototype = {};
// foo.prototype.constructor = foo;

var x = new foo();

console.log(x.__proto__ === foo.prototype); // true

Also, when you create an object like var x = {};, it is the exact same thing as:

var x = new Object();

Therefore, x.__proto__ is the object referenced by Object.protoype.


Conclusion

How does all this add up?

  • foo.prototype acts as a "blueprint" for the objects created using the function foo.

  • When we do create an object x = new foo(), JS engine stores a reference (link) to "the blueprint that was used to make x" as the __proto__ property.

When I do getPrototypeOf() I get the expected output, but when I try to use the prototype property I get undefined. Cant figure out the reason.

Object.getPrototypeOf(...) returns the __proto__ property, not prototype.

Also for line 5 return value is function(). Can some please explain does this say ? I expected an Object to be returned.

In JS, all data types have an associated "Wrapper" function.

Similar to how x = {} is the same as x = new Object(), doing function b(){} is the same as b = new Function()

since b was created invoking a function using new, it has a __proto__ property, that is the object referenecd by its constructor function's prototype. In this case, Function.prototype, which is also Function.


Still confused? I'd recommend having a good long read at http://www.javascripttutorial.net/

zhirzh
  • 3,273
  • 3
  • 25
  • 30