How do I assign a conditional variable without mutation?

蹲街弑〆低调 提交于 2019-12-05 19:33:14
Jonas Wilms

Ternary expressions can be made up other ternary expressions – allowing us to sequence logical choices

const greeting = time > 12 ? (time > 17 ? 'Evening' : 'Afternoon') : 'Morning'

However, I think it's the variable that makes the variable a variable...


You have two concerns though, and it it will benefit you to separate them

  1. determining the day period from the hour
  2. assembling the greeting string

By doing this, you avoid

  1. mutation (local reassignment of greeting)
  2. single-branch if statements
  3. imperative-style statements altogether (ie let, if, return, x = ...)

The result is two pure (referentially transparent) functions written using expressions – there is no assignment (or reassignment), and there are no side-effects.

const timeToPeriod = time =>
  time >= 17
    ? 'Evening'
    : time >= 12
      ? 'Afternoon'
      : 'Morning'

const greet = (name, time) =>
  `Good ${timeToPeriod(time)} ${name} !`
  
console.log(greet('Jonas', 9))  // Good Morning Jonas !
console.log(greet('Jonas', 13)) // Good Afternoon Jonas !
console.log(greet('Jonas', 22)) // Good Evening Jonas !
const greeting = [
  'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 
  'Morning', 'Morning', 'Morning', 'Morning', 'Morning',
  'Afternoon', 'Afternoon', 'Afternoon', 'Afternoon', 'Afternoon',
  'Evening', 'Evening', 'Evening', 'Evening', 'Evening', 'Evening', 'Evening'
]

return `Good ${greeting[time]} ${name}!`

This technically gives you the flexibility to add more times of day in the future, such as adding 'Noon' on the 12th hour. Additionally, it makes localization easier for similar reasons; Some locales may have a Noon others may not.

This was originally a joke ;)

This question is already answered but, if you have more than 3 options you could do this:

['Evening', 'Afternoon', 'Morning']
[
[17,12,0].findIndex((el) => time >= el)
]
(function (){
    const greet = (name, time) => { 
        const greetings = [ // Order is important
            {greeting: 'Evening',time: 17},
            {greeting: 'Afternoon',time: 12},            
            {greeting: 'Morning',time: -Infinity}
        ];
        const greeting = greetings.find(e=>time>=e.time).greeting;
        return `Good ${greeting} ${name}!`;
    }
    console.log(greet('Me',17));
})();

To be clear you are not doing any mutation, you are using let instead of const. Why it is not a mutation - because string is immutable in javascript. So your question is more - "How assign conditional value to const".

To be clear I don't see anything wrong with doing let here and such behavior. Until this not goes outside the function scope it is just fine to mutate it (I am talking more about general approach, for example with objects).

Immutability rule should be used for structures declared outside the scope of the function. What directly means that you should never mutate function input and never touch what not belongs to you.

To the point, my answer is - leave it as it is, for me it is much more clear than ternary operator with many conditions.

In JavaScript variables by nature cannot be made immutable. But, you can have immutable expressions, either by using a string value or by declaring a constant. This solution relies on three constants. One constant is an object containing string values corresponding to the three periods in a 24-hour time span. The second constant holds the result of testing for the time of day (tod). And, the last constant holds a function expression, i.e. an anonymous function, as follows:

let d = new Date();
let time = d.getHours();

const greeting = {
  "morn": "morning",
  "after": "afternoon",
  "evg": "evening"
};

const greet = function(strName) {
  const tod = (time < 12) ? greeting["morn"] :
    (time > 17) ? greeting["evg"] : greeting["after"];

  let salutation = "Good " + tod;
  salutation += ",";
  strName += "!";

  // adding another functional programming touch
  return function() {
    console.log([salutation, strName].join(" "));
  };
};

var user = "Zander";
greet(user)();

Note that whereas a string value is immutable, the String object itself is mutable. You may add a property to that object and you may change the value of that property; see example here.

The use of keyword const creates a constant and as per MDN:

The value of a constant cannot change through re-assignment, and it can't be redeclared.

In this and the other examples where a constant is set according to the time of day vis a vis a ternary expression, the constant itself is "variable" to the extent that its value varies depending on the time of day that the script runs.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!