Posted on

Returning Multiple Values

Mozilla’s Javascript platform supports returning multiple values, as of version 1.7. I don’t know when that got incorporated into the XUL platform, but the features from 1.7 are usable there. In fact, we already use this in ColorFish:

this.getHSL = function () {
    var h, s, l;

    // ...

    return [h, s, l]
}

The last line returns an array with three values. This is how we pass back multiple values. If we are only interested in one return value then we can use this approach:

this.getHue = function(){
    return this.getHSL()[0];
}

this.getSaturation = function(){
    return this.getHSL()[1];
}

this.getLightness = function() {
    return this.getHSL()[2];
}

We can also get all of the values using destructuring binding. That is a fancy way of saying that when we assign a value, the left side of the assignment describes the shape of the value on the right side. For example:

var [h, s, l] = getHSL();
print(h);
print(s);
print(l);

On the first line, the left side matches the shape of the right side, the three-value array returned by getHSL(). If needed, we can ignore certain values.

var [h, , l] = getHSL();

// This is also legal if we don’t care about return values.  The
// difference between this and just calling getHSL() is that this
// makes it clear we are ignoring the return values.

var [,,] = getHSL();

This mechanism is intended to be the main way we pass back multiple-values in Javascript on the Mozilla platform.

But destructuring has other uses. The multiple assignments happen in parallel, not in sequence. So we can use destructuring to swap values without the need for temporary variables.

[a, b, c] = [c, a, b]

// Now a = c, b = a, and c = b

We can also use destructuring to get at objects.

var Lobby = { first: “Lobby”, last: “Jones” };

for (let [name, value] in Lobby) {
    // ...
}

Here we pull out each name and value of the properties as a pair. If we have a complex object, we can use an object on the left side of our bind to describe only the properties we want to extract into variables. Here is a good example from Mozilla’s site:

var people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith"
    },
    age: 35
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones"
    },
    age: 25
  }
];

for each (let {name: n, family: { father: f } } in people) {
    print("Name: " + n + ", Father: " + f);
}

The key part here is the object sturcture to the left of ‘in’.

{
    name: n,
    family: {
        father: f
    }
}

This tells Javascript to pull out the name property and bind its value to ‘n’, and to take out the father property from inside the family object and bind that to ‘f’. This object is just a partial blueprint of the structure of ‘people’, naming the properties that we care about.