1

I'm trying to destructure return values of a Class instance method. Condider the snippet below

//define class of birds
class Birds {
  //save each bird name 
  constructor(birdName, birdType = "Not Stated", canYouFly = true) {
    this.birdName = birdName,
      this.birdType = birdType,
      this.canYouFly = canYouFly
  }

  //METHODS
  introduce() {
    return `hello, I'm ${this.birdName} of ${this.birdType} family`;
  }

  doYouFly() {
    return this.canYouFly ? `Oh yeah! I fly baby` : `Oops! I'm not meant for that`;
  }
}

//make new bird
let roi = new Birds("Roi", "Peacock", false);

//destructure  
const { introduce, doYouFly } = roi;
console.log(introduce, doYouFly)

The code of the methods are logged to the console in this case.

Also, I tried

...
const { introduce(), doYouFly() } = roi;
...

Here, My IDE log the following error

expected Expression expected Declaration or Statement expected.

Now, my question is, is there a way to safely destructure return values of a class instance method?

trincot
  • 317,000
  • 35
  • 244
  • 286
opeolluwa
  • 96
  • 8
  • You could convert them into getters? Or use them as functions `console.log(introduce(), doYouFly())` – evolutionxbox May 12 '21 at 20:37
  • 1
    In the second example your calling functions not declaring variables. Give them a left side name in addition to the assignment value. – asawyer May 12 '21 at 20:39
  • How can that be done, I'm juzt getting started with Core JavaScripts – opeolluwa May 12 '21 at 20:40
  • Unpack and use them as functions afterwards or store them in another variable`const { introduce, doYouFly } = roi; console.log(introduce(), doYouFly())` – Jonathan Hamel May 12 '21 at 20:41
  • I'm not sure why your IDE is complaining; because it works perfectly fine for me: https://jsfiddle.net/0pdctamk/ – Ben Wainwright May 12 '21 at 20:42
  • @asawyer, I thought as much. Is there a way to achieve the desir'd result without using intermediate variables to hold values of the function call? – opeolluwa May 12 '21 at 20:42
  • Well the thing is the first one where the console is writing out the code is more or less exactly what your asking for. It's just the variables point to a function itself instead of to the result of the function - so anywhere you need the result you just invoke it just as you would any other function. This is what @JonathanHamel is pointing out in his comment above. - Edit - Or you can change the class's function definition as in trincot's answer. This makes it behave like a property getter so you would have the values not the function references. – asawyer May 12 '21 at 20:54

1 Answers1

2

In your (first) destructure assignment you are not calling the methods; you are just getting the function objects. The second attempt is indeed not valid syntax.

One way to make it work, is to define your methods as getters. So just prefix them with the keyword get:

//define class of birds
class Birds {
  //save each bird name 
  constructor(birdName, birdType = "Not Stated", canYouFly = true) {
    this.birdName = birdName,
      this.birdType = birdType,
      this.canYouFly = canYouFly
  }

  //METHODS
  get introduce() {
    return `hello, I'm ${this.birdName} of ${this.birdType} family`;
  }

  get doYouFly() {
    return this.canYouFly ? `Oh yeah! I fly baby` : `Oops! I'm not meant for that`;
  }
}

//make new bird
let roi = new Birds("Roi", "Peacock", false);

//destructure  
const { introduce, doYouFly } = roi;
console.log(introduce, doYouFly)

Note that this changes the signature of your class. You would not add parentheses anymore to these getters in order to call them. They are now accessed as if they are plain properties:

console.log(roi.introduce);
trincot
  • 317,000
  • 35
  • 244
  • 286