Search code examples
javascriptprototype-programming

Javascript prototype and __proto__ and getPrototypeOf issue


I have a simple class in javascript:

function foo() {
    this.bar = "bar";
}

var test = new foo;

console.log(foo.prototype,foo.__proto__)
/*output: foo {
               constructor: function foo() { 
               __proto__:   Object
              }
          ,
          function Empty() {}
*/
console.log(test,test.prototype,test.__proto__,test.__proto__.__proto__)
/*output: foo {
              bar: "bar"
              __proto__: foo
          }
          ,
          undefined
          ,
          foo {
              constructor: function foo() {
              __proto__: Object
          }
          ,
          Object {
              ...
          }
      */

What i dont understand:

At the first log the foo.prototype had the __proto__ attribute which was an Object At the second log the test.__proto__ had the __proto__ attribute which was an Object

When to use __proto__ and when prototype, what is the difference?


UPDATE:

In John Resig's blog in the instanceOf section there is something waht I don't understand:

If i use var asd = "asd";Object.getPrototypeOf(asd) it throws a TypeError but
If i use var dsa = new String("dsa");Object.getPrototypeOf(dsa) it returns String
But asd.constructor.prototype == dsa.constructor.prototype is true

Why is the Object.getPrototypeOf(asd) throws error? This is a string, isn't it?


Solution

  • Always use prototype or Object.getPrototypeOf.

    __proto__ is non-standard and has been deprecated by Mozilla.

    John Resig has a good blog entry about it.


    The reason why test.prototype is undefined is because you created a new object that does not have a constructor prototype. Here's an example of when to use Object.getPrototypeOf.

    js> function foo(){}
    js> typeof foo.prototype;
    object
    js> var f = new foo();
    js> typeof f.prototype;
    undefined
    js> typeof Object.isPrototypeOf(f);
    object
    js> typeof f.constructor.prototype;
    object
    js> foo.prototype === Object.getPrototypeOf(f);
    true
    js> foo.prototype === f.constructor.prototype;
    true
    

    As you can tell, inheritance in JavaScript is tricky. Lets look at an example:

    js> typeof "asdf";
    string
    js> typeof String("asdf");
    string
    

    The string literal is of type string. The same is true when calling String() as a function. Now, because of behavior of the new operator, a new object is created, with the prototype of String() as its parent.

    js> var s = new String("asdf");
    js> typeof s;
    object
    

    Because JS likes to coerce things, you can get at the string literal a few ways:

    js> s
    asdf
    js> s.valueOf();
    asdf
    js> typeof s
    object
    js> typeof s.valueOf();
    string
    

    Prototypal Inheritance in JavaScript by Crockford helped me a lot when learning about JS inheritance.

    From Mozilla's Strings page:

    String objects may be created by calling the constructor new String(). The String object wraps JavaScript's string primitive data type with the methods described below. The global function String() can also be called without new in front to create a primitive string. String literals in JavaScript are primitive strings.