1

I was learning classes in JS and if you look at the code below

class Car{
  drive(speed) {
     console.log('Drive at '+ speed)
   }
}

const car1 = new Car();

I defined function drive() inside class Car and it is clear that drive() is automatically attached to Car.prototype which ensures there is one copy of drive() and the question is if we create new instance of Car class then Is drive() copied to car1, if not, how is it possible to have one copy of drive() and by passing argument get different results.

Mamun
  • 66,969
  • 9
  • 47
  • 59
  • That's how `prototype` chain works. First, `car1` will be checked for a `drive` property. If it doesn't exist, it will be looked in `Car.prototype`. If it is not found there, it will be searched in `Object.prototype` because `Object.getPrototypeOf(Car.prototype) === Object.prototype` (methods like `toString()`) – adiga Jul 20 '19 at 05:33
  • @adiga, look, if I create more objects of Car class, will each object have its own original copy of drive() – user11807902 Jul 20 '19 at 05:39
  • No, it won't. If you update `Car.prototype.drive = `, it will affect all `Car` objects – adiga Jul 20 '19 at 05:40
  • Possible duplicate of [How does JavaScript .prototype work?](https://stackoverflow.com/questions/572897/how-does-javascript-prototype-work) – adiga Jul 20 '19 at 05:42
  • @adiga, but by having one copy of drive() in Car.prototype for all objects how can we customize drive() FOR EACH METHOD for example car1 has 90 as its speed car2 has 100 as its speed so drive() will output various results. Does it mean that each object has access to fresh drive() even if there is only one copy of drive(). Hope you got what I mean – user11807902 Jul 20 '19 at 05:46
  • because you are passing `speed` as parameter. It is not doing anything with the car instances. Since, you aren't using `this` inside `drive`, it's as if you are using `Car.prototype.drive(10)`. – adiga Jul 20 '19 at 05:47

3 Answers3

1

Yes is it available on instance of Car class, You can pass value when invoking drive function on any instance of Car class

class Car {
  drive(speed) {
    console.log('Drive at ' + speed)
  }
}

const car1 = new Car();
car1.drive('50 kmph')
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • thank you for your kind answer, look, if I create car2 object, then will car2 have its own copy of drive(). I mean, every time I create new object will each object have its own drive() because each object has its own speed – user11807902 Jul 20 '19 at 05:32
  • @user11807902 `drive` is stateless function it just console.logs so your instance of `Car` is not holding any value, you will get in console.log whatever value you're passing in `drive` function – Code Maniac Jul 20 '19 at 05:34
1

That's kind of confusion is for adding so much "sugar" to our classes without to know what it is happening.

Your class is defined using ES6

class Car {
  drive(speed) {
    console.log('Drive at ' + speed)
  }
}

Next what you do is construct an object using your class, using new

The first question is what the new keyword does?

  • A new object is created, and this inherits from Car prototype
  • This is attached to this newly created object

So, by doing const car1 = new Car();, you get a new object wherein its prototype you get the drive function.

In ES5 your class is written by using a constructor function.

function Car() {}

Car.prototype.drive = function (speed) { console.log(speed); }

Now, you can do: console.log(Car.prototype.constructor); and you will see that the constructor function shown is Car.

If you want to create a subclass in ES6 you use the extends keyword but in ES5 what is really happening is:

Function SuperFastCar() {}

SuperFastCar.prototype = Object.create(Car.prototype);
SuperFastCar.prototype.turbo = function (maxSpeed) { console.log(maxSpeed); }
SuperFastCar.prototype.constructor = SuperFastCar;

Object.create creates a new object using as the prototype the provided object. Also, we need to overwrite the constructor, if not Car constructor function will appear for SuperFastCar.

F.bernal
  • 2,594
  • 2
  • 22
  • 27
  • thank you for your kind answer, yeah all is clear except for one thing. Ok, the reason for putting function into prototype is to ensure there is one instance of the function to save memory. Ok but imagine we have function with parameter and every time we create object with different parameters then output will be different. What confuses me is how car2 accesses fresh drive() since car1 already used it with different parameter. Hope it is clear – user11807902 Jul 20 '19 at 16:32
  • As I say, each time you create an object with NEW a new object is created, and in the prototype of this object, the function (drive) is added, it doesn't mind if the function has or not parameters. Moreover, a function execution hasn't state unless you are using class atributes inside the function with THIS. But as I said too, the THIS is the new created object so, there is no problems with it. – F.bernal Jul 20 '19 at 16:42
  • ok perfect, you know, just last question why did you declare Car.prototype.drive = function (speed) { console.log(speed); } outside of the function Car? – user11807902 Jul 20 '19 at 17:04
  • That is what ES6 do for you when you declare a function inside a class. – F.bernal Jul 20 '19 at 17:06
  • yes I know but why? just what if we put Car.prototype.drive = function (speed) { console.log(speed); } INSIDE the function I think it is not good but I do not know WHY? :) – user11807902 Jul 20 '19 at 17:09
  • If you add the definition inside Car, each time you want to create a new object the drive function will be overwritten – F.bernal Jul 20 '19 at 17:29
0

Everything you create inside the prototype will be shared between all instances of the class. Keep in mind that in the methods you define inside the prototype you are typically defining the behaviour of your class (which should be shared between all instances).

Now, when you define a second instance of your Car class, both the first and the second instance share the drive method. But that doesn't mean that they can not call the method with different values:

class Car {
    drive(speed) {
        console.log('Drive at '+ speed)
    }
}

const car1 = new Car();
car1.drive('10mph'); // ---> Will log "Drive at 10mph"

const car2 = new Car();
car2.drive('15mph'); // ---> Will log "Drive at 15mph"
mgarcia
  • 5,669
  • 3
  • 16
  • 35
  • thank you for your kind answer, yeah all is clear except for one thing. Ok, the reason for putting function into prototype is to ensure there is one instance of the function to save memory. Ok but imagine we have function with parameter and every time we create object with different parameters then output will be different. What confuses me is how car2 accesses fresh drive() since car1 already used it with different parameter. Hope it is clear – user11807902 Jul 20 '19 at 16:10