Too clever for your own good?
Tags: javascript, todayilearned
Published: 2019-10-04 04:49:35

JavaScript is great for prototyping ideas. Okay, so it's a [prototype-based language](https://stackoverflow.com/questions/186244/what-does-it-mean-that-javascript-is-a-prototype-based-language) but we probably mean slightly different things.

I wanted to do a calculated selection of a value and quickly threw together the following, which takes a parameter, compares it to an array of possible match/result pairs, along with a default value in the event that there's no match in the match/result pairs. I also coded in the possibility of embedding a function.

Here's the ES3 code
```javascript
function selector(target, casevalues, defaultvalue) {
    for (var i = 0; i < casevalues.length; i++) {
        var caseval = casevalues[i];
        if ("string" === typeof caseval[0]) {
            if (target === caseval[0]) {
                return caseval[1];
            }
        } else { //assume function
            return caseval[0](target);
        }
    }
    return defaultvalue;
}
```
and the equivalent ES5 code
```javascript
const selector = (target, casevalues, defaultvalue) => {
    for (let i = 0; i < casevalues.length; i++) {
        const caseval = casevalues[i];
        if ("string" === typeof caseval[0]) {
            if (target === caseval[0]) {
                return caseval[1];
            }
        } else { //assume function
            return caseval[0](target);
        }
    }
    return defaultvalue;
}
```
Evaluating that can be done like this (ES3 then ES5):
```javascript
var target = selector("page value", [
            ["domain", "domain"],
            ["subdomain", "subdomain"],
            [function (x) {
                    return x === "page value" ? "page" : x
                }
            ]], "");
```
```javascript
let target = selector("page value", [
            ["domain", "domain"],
            ["subdomain", "subdomain"],
            [x => x === "page value" ? "page" : x
            ]], "");
```
So pretty cool, right? We-e-e-ell, maybe not. The whole thing might just as readily be expressed in a shorter piece of code, and done inline, using in-place evaluation. ES3 and ES5:
```javascript
var target = (function (item) {
    switch (item) {
    case "page value":
        return (function (x) {
          return x === "page value" ? "page" : x
        }(item));
    case "domain":
        return "domain";
    case "subdomain":
        return "subdomain";
    }
    return "";
}("page value"));
```
```javascript
const target = (item => {
    switch (item) {
    case "page value":
        return (x => x === "page value" ? "page" : x)(item);
    case "domain":
        return "domain";
    case "subdomain":
        return "subdomain";
    }
    return "";
})("page value");
```
Cost-benefit is the key here. Where I was wanting the original selector, the inline worked better and was more efficient. Maybe you do want to have a generalised `selector` function, in which case something like the above would work. An improvement might be to pass in an array of key-value-pair objects instead of an array of match/result pairs. 

Okay, that's me done with thinking aloud for now. Kudos to [Lebab](https://lebab.unibtc.me/editor/)'s online editor for helping with the ES3 to ES5 conversions.