0

This is a part of my class Bird:

class Bird
{
    constructor()
    {
        this.imagePaths = ['./assets/Bill-Gates.png', './assets/steve-jobs.png', './assets/zuckerberg.png'];
        this.elementImg.src = this.changeImage();
        this.speed = Math.floor((Math.random() * 5) + 5);
    }

In the class's constructor, I want to react to different speeds and assign different images to the object:

changeImage = () => {
    if (this.speed < 6) {
        return this.imagePaths[0];
    }
    else if (this.speed < 9) {
        return this.imagePaths[1];
    }
    else if (this.speed > 9) {
        return this.imagePaths[2];
    }
}

I try to do this by assigning the images to the elementImg.src property via a method. But the method does not return the desired value. Why?

Krisztián Balla
  • 19,223
  • 13
  • 68
  • 84
H.Solo
  • 79
  • 1
  • 11

1 Answers1

2

in a Class the functions look like this:

changeImage(){
    if (this.speed < 6) {
        return this.imagePaths[0];
    } else if (this.speed < 9) {
        return this.imagePaths[1];
    } else if (this.speed > 9) {
        return this.imagePaths[2];
    }
}

If that was the question?

Here is the full Code which should work.

class Bird {
    constructor() {
        this.imagePaths = ['./assets/Bill-Gates.png', './assets/steve-jobs.png', './assets/zuckerberg.png'];
        this.speed = Math.floor((Math.random() * 5) + 5);
        this.elementImg.src = this.changeImage();
    }
    changeImage(){
        if (this.speed < 6) {
            return this.imagePaths[0];
        } else if (this.speed < 9) {
            return this.imagePaths[1];
        } else if (this.speed > 9) {
            return this.imagePaths[2];
        }
    }
}
Andre
  • 458
  • 5
  • 10
  • after I change the method like this he gives me this error "Expected to return a value at the end of method 'changeImage' ". – H.Solo Oct 07 '18 at 11:20
  • if it doesn't return a value, then "this.speed" is 9. You don't have a case for that. – Andre Oct 07 '18 at 11:31
  • 1
    Um, `changeImage = () => { }` is actually [valid](https://stackoverflow.com/questions/31362292/how-to-use-arrow-functions-public-class-fields-as-class-methods), the real answer is the other change you have made... – Jonas Wilms Oct 07 '18 at 11:44
  • 1
    @h.solo thats a linter hint, not an error, so you can safely ignore it (as it doesnt cause any problems here) – Jonas Wilms Oct 07 '18 at 11:45
  • @Jonas Wilms, thanks for the hint. I didn't know that as well. But since I didn't understand the question at first, I thought it was what he asked for :-) – Andre Oct 07 '18 at 11:54
  • @JonasWilms: `() => {}` is not valid in this case because arrow function statically bind `this` upon declaration therefore the `this` in changeImage will be different form the one created in the constructor (which will only exist when the the constructor is called, not when changeImage is defined) – slebetman Oct 07 '18 at 12:03
  • @slebetman wrong. class fields are initialized after the constructor, and are bound to the instances context – Jonas Wilms Oct 07 '18 at 12:05
  • @JonasWilms Then `() => {}` would not be valid in this case because class fields are processed after constructor call therefore it's `this` will not exist at the time the constructor is called. Even the function would not exist at the time the constructor is called – slebetman Oct 07 '18 at 12:07
  • @JonasWilms: Also, I didn't think javascript classes can have fields/properties? Do you have documentation for how that would work? MDN doesn't mention anything about properties. JS classes can only have methods according to most docs I read. You are supposed to declare instance properties inside the constructor and this include functions, not just numbers and strings – slebetman Oct 07 '18 at 12:10
  • @slebetman if you would click on the link above you would see that it is a "proposal", to be found [here](https://tc39.github.io/proposal-class-public-fields/), and i was wrong, class fields are initialized before the constructor is executed (apologies, I haven't used them much yet) – Jonas Wilms Oct 07 '18 at 12:16
  • So now I've tested it myself and `changeImage = () => { }` throws `Uncaught SyntaxError: Unexpected token =` – Andre Oct 07 '18 at 12:17
  • 1
    @andre cause its a proposal (!!) you have to use Babel or tsc to compile it down to ES7. – Jonas Wilms Oct 07 '18 at 12:18
  • In which case, even if the proposal were to be approved it's not a good idea to use arrow functions in classes. While it would work for the constructor it would make the method uninheritable – slebetman Oct 07 '18 at 12:21
  • @slebetman It is actually a really good idea, class properties are inherited. It resolves the "class method as a callback" problem, e.g. `setTimeout(this.remove, 100)` – Jonas Wilms Oct 07 '18 at 12:26
  • @JonasWilms For classes you never intend to inherit yes. But arrow functions breaks the functionality of `this`. Therefore you cannot inherit from the class afterwards. – slebetman Oct 08 '18 at 03:18
  • @slebetman what?! I have no idea what you are talking about. I guess you should play a but with class fields to understand their usage. – Jonas Wilms Oct 08 '18 at 09:33