简体   繁体   中英

Expand a ternary statement or switch to if-else

I have the following which works fine with two conditions:

var value = this.value === "foo" ? function(d) {
    return d.foo;
} : function(d) {
    return d.bar;
};

What am I doing wrong when I try to expand the above to the following using if-else ?

var value = 
if (this.value === "foo") {
        function(d) {
            return d.foo;
        };
    } else
if (this.value === "bar") {
    function(d) {
        return d.bar;
    };
} else {
    function(d) {
        return d.qux;
    };
}

I'm happy to stick with operators or switching to if-else : whatever is more readable for me.

if cannot be used on the right-hand side of an assignment statement (which is part of why we have the conditional operator).

Instead, assign in each branch:

var value;
if (this.value === "foo") {
    value = function(d) {
        return d.foo;
    };
} else if (this.value === "bar") {
    value = function(d) {
        return d.bar;
    };
} else {
    value = function(d) {
        return d.qux;
    };
}

Although note that that particular code can be simplified:

var key = this.value == "foo" || this.value == "bar" ? this.value : "qux";
var value = function(d) {
    return d[key];
};

You can't use a conditional block statement to assign a value to a variable. You can use the ternary operator you were using in the first example and double it:

var value = (this.value === "foo") ? function(d) {
    return d.foo;
} : (this.value === "bar") ? function(d) {
    return d.bar;
} : function(d) {
    return d.qux;
};

The first once works because the ternary operator by default returns the result of either first or second expression based on the condition

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator

while the if-else block only check for the condition and do not return anything by default and thats why can not be on the right side of any assignment.

There's another approach. It doesn't quite fit these requirements, but I do assume that these requirements aren't your precise ones (or do you have actual needs for 'foo', 'bar', and 'quz' :-) ? )

You can capture the value in a wrapping function:

function createValueFunc(val) {
    return function(d) {
        return d[val];
    };
}

value = createValueFunc(this.value);

This does not handle your else case, so it may be useless to you. But if it's useful, you can simplify it in ES6 to:

createValueFunc = (name) => (obj) => obj[name];

You'll find such a function in many utility libraries. Underscore calls it property . Ramda calls it prop . Sometimes I've seen it called get as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM