1

I'm trying to understand what actually happens when you create a new instance of a class with ES6. As far as I can tell, a new instance is created with properties as defined in the constructor and then the rest of the methods in the class are actually properties on the prototype object

For example

class Dog {
    constructor(name){
      this.name = name
    }

    speak (){
        console.log('Woof')
    }
}

Would be the equivelant to

function Dog(name){
    this.name = name;
}

Dog.prototype.speak = function () {
    console.log('Woof');
}

In the class example. If I create an instance of my Dog class, Is the prototype of that method pointing to the Dog class itself or is it a completely new object? Because when I Object.getPrototypeOf(myDog) it returns Dog {}.

31piy
  • 23,323
  • 6
  • 47
  • 67
juicy89
  • 448
  • 5
  • 14
  • 2
    Possible duplicate of [classical inheritance vs prototypal inheritance in javascript](https://stackoverflow.com/questions/19633762/classical-inheritance-vs-prototypal-inheritance-in-javascript) – justMe Aug 13 '18 at 14:40
  • 2
    The JS class syntax is just syntax sugar for the prototypes. In both cases `.getPrototypeOf()` will point to the object `Dog.prototype`. Internally the class syntax will be 'rewrittten' to the prototype syntax. The way it's shown in the debugger will depend on which browser / debugger. – Shilly Aug 13 '18 at 14:41
  • I see, So this is acting pretty much the same. So when I set a speak method in the class Dog, is that actually setting a method named speak on Dog.prototype? – juicy89 Aug 13 '18 at 14:44
  • 1
    yes, all the methods you define with the class syntax become functions inside the prototype object. – Shilly Aug 13 '18 at 14:45
  • Thanks Shilly, this makes it a lot clearer! – juicy89 Aug 13 '18 at 14:46

1 Answers1

1

They are functionally exactly the same. Here are some interesting properties about prototypes and classes to point out though:

class Dog1 {
    constructor(name){
      this.name = name
    }

    speak (){                    // adds speak method to the prototype of Dog1
        console.log('Woof')
    }
}

Dog1.prototype.speak = () => {    // overwrites speak method to the prototype of Dog1
 console.log('Different Woof');
}

console.log(typeof Dog1); // Class keyword is just syntactic sugar for constructor function

const newDog = new Dog1('barkie');

newDog.speak();

/////////////////////////////

function Dog2(name){
    this.name = name;
}

Dog2.prototype.speak =  () => {
    console.log('Woof');
}

const aDog = new Dog2('fluffy');

aDog.__proto__.speak();  // the __proto__ property references the prototype
aDog.speak();  // the __proto__ property is not necessary, it will automatically climb the protochain if the property is not found on the object itself.

I left some comments in order to point out the quirks which can be a bit hard to grasp. I you have any further questions about it you can leave a comment. Hopefully this is helpful to you.

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155