0

I created a Car (Auto in German) class to simulate the speed of a Car. I want the Ford object to start at 0 and increase its speed every second by 15. For this, I used setInterval. But, when I call the plus() function in setInterval, it gives me back NaN every second. When I just call the method by using Ford.plus();, It works perfectly and gives back an Integer

//require "prompt-sync"
const prompt = require("prompt-sync")({ sigint: true });

//Auto class
class Car{
    constructor(brand, speed, maxSpeed, currentSpeed){
        this.carBrand = brand;
        this.carSpeed = speed;
        this.carMaxSpeed = maxSpeed;
        this.carCurrentSpeed = currentSpeed;
    }

    drive(){
        if(this.carCurrentSpeed >= this.carMaxSpeed){
            clearInterval(inter);
            console.log("too fast");
        }else{
            this.carCurrentSpeed = this.carCurrentSpeed + this.carSpeed;
            console.log(this.carBrand + " has a speed of " + this.carCurrentSpeed + " km/h");
        }
    }    
}


//gameloop
for(var i = 0; i < 3; i++){
    //infos from usr
    let brand = prompt("what brand is your car? ");
    let speed = parseInt(prompt("How much speed does your car gain per second? "));
    let maxSpeed = parseInt(prompt("what is the maximum speed of your car? "));
    
    //create Object
    var usrAuto = new Car(brand, speed, maxSpeed, 0);

    let inter =setInterval(function() {
        usrAuto.drive.call(usrAuto)
      }, 1000);
}
asgr
  • 35
  • 6
  • 2
    `setInterval` will set `this = window`, so you need to use `setInterval( Ford.plus.bind(Ford) )`. Also, don't use `PascalCase` for variables, use `camelCase` (i.e. rename `var Ford` to `var ford`). – Dai Jul 24 '22 at 11:40
  • That works! Thanks! But what does Ford.plus.bind(Ford) ) do different then Ford.plus? I don't quite get what you mean with: setInterval will set this = window – asgr Jul 24 '22 at 11:46
  • 1
    @Dai _"Also, don't use PascalCase for variables..."_ - That might be best practice for JavaScript but in the end it's just an opinion... – Andreas Jul 24 '22 at 11:46
  • 1
    @Andreas It's the established standard industry practice. Sure, nobody will care what casing you use for variables in code that you never show anybody else, but as soon as you ask fellow developers about it you should follow the conventions that make the code easier to read and understand for everyone. Just like nobody forces you to spell English words correctly, but if you want to communicate with other people and not have them ignore your messages you should apply standard grammar rules. (Now *that's* an opinion :-P) – Bergi Jul 24 '22 at 12:15

1 Answers1

1

The bind function binds an object to a function to be used as this for that function. It returns the function itself, having that object bound to it.

setInterval( Ford.plus.bind(Ford), 1000 )

Personally, I don't like this new function introduced in a recent JavaScript version. Instead I would have:

setInterval(function() {
  Ford.plus.call(Ford)
}, 1000)
IT goldman
  • 14,885
  • 2
  • 14
  • 28
  • `bind()` is hardly recent, [it was added in ES5 in 2009](https://stackoverflow.com/q/9625600/159145), that's _13 years ago_. Also, a problem with your approach is it creates a closure with variable-capture which has higher memory usage and often surprises some people, [such as when used in a loop](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). – Dai Jul 24 '22 at 12:40
  • Thank you. I am not sure performance should differ as `bind` is a syntactic sugar technically. As for the loop problem; however confusing a closure is the classic *solution* not the *problem*. – IT goldman Jul 24 '22 at 13:00