2017-07-26 66 views
4

我堅持嚴格的函數式編程原則,沒有變異。如何分配一個沒有突變的條件變量?

如何以不改變greeting變量的方式編寫類似以下代碼的內容,並且不會在每個if塊中將其返回?

const greet = (name, time) => { 
    let greeting = 'Morning'; 

    if(time >= 12) { 
    greeting = 'Afternoon'; 
    } 
    if(time >= 17) { 
    greeting = 'Evening'; 
    } 

    return `Good ${greeting} ${name}!`; 
}; 

如果這只是兩個條件,我會做以下,但是當有3個條件,它不會工作:

const greeting = time > 12 ? 'Afternoon' : 'Morning' 

回答

9

Ternary expressions可以由其他三元表達 - 讓我們序邏輯的選擇

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

不過,我認爲這是變量,使雜物竹葉提取一個變量 ...


你有2個擔憂雖然,這將有利於你把它們分開

  1. 從小時
  2. 組裝確定一天期問候字符串

通過這樣做,您避免了

  1. 突變(的greeting局部再分配)
  2. 單支如果語句
  3. 命令式的語句完全(即letifreturnx = ...

結果使用表達式編寫的兩個純(referentially transparent)函數 - 我有沒有分配(或重新分配),也沒有副作用。

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 !

+1

漂亮的總哈哈 –

+3

「_i認爲它的變量使變量變量_」 - 使我的日子, – Frits

+1

聰明地使用三元表達式內嵌套三元組。 – slevy1

7
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}!` 

這在技術上爲您提供了靈活地添加一天多次在未來,如在12小時,之後加入'Noon'。此外,由於類似的原因,它使本地化更容易;有些地區可能有其他地區可能不會。

這本來是一個笑話;)

2

這個問題已經回答了,但如果你有超過3個選項,你可以這樣做:

['Evening', 'Afternoon', 'Morning'] 
[ 
[17,12,0].findIndex((el) => time >= el) 
] 
0

在本質上的JavaScript變量不能進行一成不變。但是,通過使用字符串值或聲明常量,您可以擁有不可變的表達式。這個解決方案依賴於三個常量。一個常量是一個對象,其中包含與24小時內的三個時間段相對應的字符串值。第二個常量表示測試一天中的時間(tod)的結果。並且,最後的恆定保持函數表達式,即匿名函數,如下所示:

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)();

注意,而一個字符串值是不可變的,在字符串對象本身是可變的。您可以向該對象添加屬性,並且可以更改該屬性的值;請參閱示例here

使用關鍵字常量的創建一個常數,按MDN

一個常量的值無法通過重新分配改變,並且它 不能重新聲明。

在此,並且其中一個常數根據一天相一相的三元表達的時間設定的其他例子中,常數本身是「可變的」,以使得其值變化的程度取決於一天中的時間該腳本運行。

2
(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)); 
})(); 
1

要清楚你沒有做任何突變,你使用let而不是const。爲什麼它不是一個變種 - 因爲字符串在JavaScript中是不可變的。所以你的問題更多 - 「如何將條件值賦值給const」。

要清楚我沒有看到有什麼不對這裏和這樣的行爲。直到這不會超出函數範圍,它可以很好地改變它(我正在談論更多關於一般方法,例如對象)。

對於在函數範圍外聲明的結構,應該使用不變性規則。直接意味着你不應該改變功能輸入,也不要觸摸不屬於你的東西。

關於這一點,我的答案是 - 保持原樣,對我來說,它比三元算子更清晰,有很多條件。

相關問題