有没有更简洁的方法在js中编写一组基于时间的条件?

Is there a neater way to write a set of time based conditions in js?

本文关键字:一组 于时间 条件 时间 js 方法 有没有 简洁      更新时间:2023-09-26

嘿,我有以下代码,但我很好奇是否有一种速记或更好/更整洁的方式来编写这样一段看似繁琐的代码。

var time = new Date().getHours();
var greet;
if ( time >= 0 && time < 4 ) {
    greet = 'Wow you''re up late! Good morning.';
}
else if ( time >= 4 && time < 12 ) {
    greet = 'Good morning.';
}
else if ( time >= 12 && time < 17 ) {
    greet = 'Good afternoon.';
}
else if ( time >= 17 && time <= 23 ) {
    greet = 'Good evening.';
}
document.querySelector('.js-greet').innerHTML = greet;

另一种选择

let time = new Date().getHours();
let hours = [4, 12, 17, 24];
let greetings = ['Wow you''re up late! Good morning.', 'Good morning.', 'Good afternoon.', 'Good evening.'];
console.log(greetings[hours.findIndex(hour => hour > time)]);

作为另一种选择,您可以定义一个每小时一个值的数组。每个值都是要显示的消息的ID。这个数组甚至可以是字符串,因为字符串也允许通过数组表示法访问每个字符:

var time = new Date().getHours();
var greet = ['Wow you''re up late! Good morning.',  
             'Good morning.',
             'Good afternoon.',
             'Good evening.']['000011111111222223333333'[time]];
console.log(greet);

首先,您不需要下界,因为getHours永远不会返回< 0,并且在else if s上,如果更早的边界匹配,您将无法到达那里;最后一个根本不需要任何条件,所以作为第一个swing:

var time = new Date().getHours();
var greet;
if ( time < 4 ) {
    greet = 'Wow you''re up late! Good morning.';
}
else if ( time < 12 ) {
    greet = 'Good morning.';
}
else if ( time < 17 ) {
    greet = 'Good afternoon.';
}
else {
    greet = 'Good evening.';
}
document.querySelector('.js-greet').innerHTML = greet;

(还删除了在我看来不必要的垂直空白)

除此之外,你开始进入消息的映射,这些将是一个特定时间的列表,而不是范围,所以这可能已经足够好了。

那么,您可以大大简化您的if语句,因为已经检查了(在早期的if语句中)小于您希望的范围的值。此外,getHours()只返回0到23之间的整数,因此没有理由检查这些范围之外的数字。

var time = new Date().getHours();
var greet;
if ( time < 4 ) {
    greet = "Wow you're up late! Good morning.";
} else if ( time < 12 ) {      //You can't get here if time < 4; no need to check again.
    greet = 'Good morning.';
} else if ( time < 17 ) {      //You can't get here if time < 12; no need to check again.
    greet = 'Good afternoon.';
} else {                       //You can't get here if time < 17; no need to check again.
    greet = 'Good evening.';
}
document.querySelector('.js-greet').innerHTML = greet;
<div class="js-greet"></div>

此外,您可以通过将'Good evening.'赋值给greet作为初始值来消除最终的else

var time = new Date().getHours();
var greet = 'Good evening.'; //Remains the value for greet for time >=17
if ( time < 4 ) {
    greet = "Wow you're up late! Good morning.";
} else if ( time < 12 ) {
    greet = 'Good morning.';
} else if ( time < 17 ) {
    greet = 'Good afternoon.';
}
document.querySelector('.js-greet').innerHTML = greet;
<div class="js-greet"></div>

很高兴你问我如何改进!我经常看到这样的代码,有很多方法可以简化它。

您的原始代码

if ( time >= 0 && time < 4 ) {
    greet = 'Wow you''re up late! Good morning.';
}
else if ( time >= 4 && time < 12 ) {
    greet = 'Good morning.';
}
else if ( time >= 12 && time < 17 ) {
    greet = 'Good afternoon.';
}
else if ( time >= 17 && time <= 23 ) {
    greet = 'Good evening.';
}

改善# 1

这里我们采取一些第一步,删除冗余代码/简化东西

if(time < 0) {
    //dont do anything
}
// now we can take "time >= 0 && " out, making it easier to read
else if (time < 4) {
    greet = 'Wow you''re up late! Good morning.';
}
//here, we don't actually need to check if time >= 4, because if it wasn't
//it would have been dealt with by a previous condition
else if (time < 12) {
    greet = 'Good morning.';
}
//and the same for the rest of them
else if (time < 17 ) {
    greet = 'Good afternoon.';
}
//lets keep things consistant by using "time < 24" rather than "time <= 23"
else if (time < 24) {
    greet = 'Good evening.';
}

改善# 2

重构可以进一步简化代码,所以让我们把这段代码放入一个函数

//in this function we can take advantage of the order of operations 
//to simplify further
function getGreeting(time){
    //returning early when things go wrong is always a good idea
    if(time < 0) {
        return null;
    }
    //We dont need 'else' because we are returning when a condition is met,
    //and the app doesn't have a chance to try the other conditionals
    //the less 'else's you have the better the code IMO :)
    if (time < 4) {
        //return our string instead of setting it!
        return 'Wow you''re up late! Good morning.';
    }
    if (time < 12) {
        return 'Good morning.';
    }
    if (time < 17 ) {
        return 'Good afternoon.';
    }
    if (time < 24) {
        return 'Good evening.';
    }
}
//then call the function 
greet = getGreeting(time);

改善# 3

我们可以做得更好…使用数据结构!

function getGreeting(time){
    //we still check for stuff that shouldn't happen
    if(time < 0) {
        return null;
    }
    //Here we declare a 'greetings' array. In the array there are objects!
    //each object has a field for time start and end as well as a greeting
    //the thing that makes this approach so neat is that adding more data in
    //the future
    //is dead easy, and the data can now come from a database or whatever
    //you want.
    var greetings = [
        {
            timeStart: 0,
            timeEnd: 4,
            greeting: 'Wow you''re up late! Good morning.'
        },
        {
            timeStart: 4,
            timeEnd: 12,
            greeting: 'Good morning.'
        },
        {
            timeStart: 12,
            timeEnd: 17,
            greeting: 'Good afternoon.'
        },
        {
            timeStart: 17,
            timeEnd: 24,
            greeting: 'Good evening.'
        }
    ];
    //We can add as many new items to the greetings array without ever
    // touching this again!
    for(var i = 0; i < greetings.length; i++)
    {
        if(time >= greetings[i].timeStart && time < greetings[i].timeEnd)
        {
            return greetings[i].greeting;
        }
    }
}
//then call the function 
greet = getGreeting(time);