4

I am a newbie in Javascript and I just finished the long Javascript course in codeAcademy. I have some question regards prototype. I understand that prototype is mostly used for inheritance and also to dynamically define methods to an object.

But I still have some questions. Look at my code. I defined a toString in the object Animal and also another toString, using prototype. When I run it, why it displays : [Object] Dumbo 4 and not [Proto] Dumbo 4?

 function Animal(name, numLegs){
      this.name = name;
      this.numLegs = numLegs;

       this.toString = function(){
        return "[Object]" + this.name  + " " + this.numLegs + "\n";
        };
    }

    Animal.prototype.toString = function(){
     return "[Proto]" + this.name  + " " + this.numLegs + "\n";
    };

    var animal = new Animal("Dumbo", 4);
    console.log(animal.toString());
Dimitri
  • 8,122
  • 19
  • 71
  • 128
  • 2
    You're overriding `toString` in runtime every time you create an object. Put `console.log` with some message before `Animal.prototype.toString` and another before `this.toString` – zerkms Oct 10 '13 at 09:03
  • As zerkms said, but not really overwriting, more shaddowing. Property resolution starts on the object itself, then looks at properties on the `[[Prototype]]` chain. So the one on the instance (assigned in the constructor, so each instance has its own copy) is found before the inherited one (which each instance shares). – RobG Oct 10 '13 at 09:25
  • The answers are already given but you may want some more info to understand what is going on. An explanation about prototype with sample code: http://stackoverflow.com/a/16063711/1641941 What is `this` in JavaScript: http://stackoverflow.com/a/19068438/1641941 – HMR Oct 10 '13 at 11:31

2 Answers2

5

JavaScript is a prototypal object-oriented programming language which simply means that objects inherit from other objects. In JavaScript when a property is not found on an object then the interpreter tries to find it in the object's prototype chain. If the object is not found in the object's prototype chain either then the interpreter returns undefined:

        null
          ^
          | [prototype]
          |
+------------------+
| Object.prototype |
+------------------+
          ^
          | [prototype]
          |
+------------------+
| Animal.prototype |
+------------------+
          ^
          | [prototype]
          |
   +------------+
   | new Animal |
   +------------+

As you can see var animal = new Animal("Dumbo", 4) inherits from Animal.prototype. Hence when you call animal.toString() it will execute the function defined inside the Animal constructor. If you delete animal.toString and then call animal.toString then it will call Animal.prototype.toString instead.

Read the following blog post to learn more about prototypal inheritance in JavaScript: Why Prototypal Inheritance Matters

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • There is sth I don't understand. Why Animal extends Animal.prototype? – Dimitri Oct 10 '13 at 09:37
  • @Dimitri `Animal` does not inherit from `Animal.prototype`. It is a function. Hence it inherits from `Function.prototype`. However when you use `new` before a function call the function call is treated as a constructor: `new` creates a new object object which inherits from the `.prototype` of the constructor function and binds the newly created object to `this` inside the constructor. Hence `new Animal` inherits from `Animal.prototype`. I know that it is a little confusing. Perhaps the following answer would help you understand what is really happening http://stackoverflow.com/a/8096017/783743 – Aadit M Shah Oct 10 '13 at 09:54
0

It's only natural for properties defined on object itself to take precedence over ones defined somewhere in it's prototype chain.

Leonid
  • 3,121
  • 24
  • 31