foreach跳出本次循環「js判斷空對象的方法」

JavaScript是一種發展迅速的語言。這篇文章,我想展示一些有關如何在JavaScript中應用函數式編程的示例。

JavaScript中的函數式編程

即使函數式編程可以極大地改善應用程序的代碼,但其原理在開始時可能會有些挑戰。由於詳細解釋所有這些都將花費大量時間,因此我們決定使用兩個實際的代碼示例來介紹這些概念

解析:JavaScript中的函數式編程

1.Maybe Monad

在第一個示例中,我們找到一種避免驗證變數是否為Null的方法。假設在我們的應用程序中,我們可以找到具有以下格式的用戶:

const someUser = {
 name: 'some_name',
 email: 'some@email.com',
 settings: {
  language: 'sp'
 }
};

有一個功能,可以以用戶設置的語言返回歡迎消息。

const allGreetings = {
 'en': '嗨',
 'sp': '你好',
 'fr': '歡迎你'
};
const getGreetingForUser = (user) => {
 //將要執行
}

來看一個遵循命令式模型的「 getGreetingForUser」函​​數的實現:

const getGreetingForUser = (user) => {
 if (!user) {
   return allGreetings.en;
 }
 if (user.settings && user.settings.language) {
   if (allGreetings[user.settings.language]) {
     return allGreetings[user.settings.language]
   } else {
     return allGreetings.en;
   }
 } else {
   return allGreetings.en;
 }
};
console.log(getGreetingForUser(someUser));

如上面所看到的,必須檢查用戶是否已經存在,是否已設置語言,以及是否已準備好歡迎消息。如果出現問題,我們將以默認語言返回一條消息。

現在,讓我們看一下相同的函數,但是這次我們將在其實現中使用函數式編程:

const getGreetingForUser = (user) => {
  return RamdaFantasy.Maybe(user)
    .map(Ramda.path(['settings', 'language']))
    .chain(maybeGreeting);
};
const maybeGreeting = Ramda.curry((greetingsList, userLanguage) => {
  return RamdaFantasy.Maybe(greetingsList[userLanguage]);
})(allGreetings);
console.log(getGreetingForUser(someUser).getOrElse(allGreetings.en));

為了處理可能為null或未定義的情況,我們將使用Maybe Monad。這使我們可以在對象周圍創建包裝器,並為空對象分配默認行為。

解析:JavaScript中的函數式編程

讓我們比較兩種解決方案:

//代替驗證用戶是否為空
if (!user) {
  return allGreetings.en;
}
//我們將用:
RamdaFantasy.Maybe(user) //我們將用戶添加到包裝器中
//代替:
 if (user.settings && user.settings.language) {
   if (allGreetings[user.settings.language]) {
//我們將用:
 <userMaybe>.map(Ramda.path(['settings', 'language'])) //如果存在數據,映射將會用它
//不是在else中返回默認值:
 return indexURLs['en'];
.getOrElse(allGreetings。EN)
// 指定的默認值。

2 Either Monad

當我們知道存在空錯誤時的默認行為時,Maybe Monad非常有用。

但是,如果我們有一個引發錯誤的函數,或者我們將各種引發錯誤的函數鏈接在一起,並且我們想知道哪個發生了故障,則可以改用Either Monad。

解析:JavaScript中的函數式編程

現在,讓我們假設我們要計算產品的價格,同時考慮增值稅和可能的折扣。我們已經有了以下代碼:


const withTaxes = (tax, price) => {
2
 if (!_.isNumber(price)) {
3
 return new Error("Price is not numeric");
4
 }
5
 return price + (tax * price);
6
};
7
const withDiscount = (dis, price) => { 
8
  if (!_.isNumber(price)) { 
9
    return new Error("Price is not numeric"); 
10
  } 
11
  if (price < 5) 
12
    return new Error("Discounts not available for low-priced items"); 
13
  } 
14
  return price - (price * dis);5
}; 
const isError = (e) => e && e.name === 'Error';
const calculatePrice(price, tax, discount) => { 
//將要執行
}

讓我們來看一個遵循命令式模型的「 calculatePrice」函數的實現:

const calculatePrice = (price, tax, discount) => {
  const priceWithTaxes = withTaxes(tax, price);
  if (isError(priceWithTaxes)) {
    return console.log('Error: ' + priceWithTaxes.message);
  }
  const priceWithTaxesAndDiscount = withDiscount(discount, priceWithTaxes);
  if (isError(priceWithTaxesAndDiscount)) {
    return console.log('Error: ' + priceWithTaxesAndDiscount.message);
  }
  console.log('Total Price: ' + priceWithTaxesAndDiscount);
}
//我們計算出價值25的產品(含21%的增值稅和10%的折扣)的最終價格。
 calculatePrice(25, 0.21, 0.10)

現在,讓我們了解如何使用Either Monad重寫此函數。

都有兩個構造函數,Left和Right。我們要實現的是將異常存儲到Left構造函數,並將正常結果(快樂路徑)存儲到Right構造函數。

首先,將更改已經存在的withTaxes和withDiscount函數,以便在出現錯誤時它們返回Left,在一切正常的情況下返回Right:

const withTaxes = Ramda.curry((tax, price) => {
  if (!_.isNumber(price)) {
    return RamdaFantasy.Either.Left(new Error("Price is not numeric"));
  }
  return RamdaFantasy.Either.Right(price + (tax * price)); 
});
const withDiscount = Ramda.curry((dis, price) => {
  if (!_.isNumber(price)) {
    return RamdaFantasy.Either.Left(new Error("Price is not numeric")); 
  }
  if (price < 5) { 
    return RamdaFantasy.Either.Left(new Error("Discounts not available for low-priced items")); 
  } 
  return RamdaFantasy.Either.Right(price - (price * dis)); 
});

然後,我們為Right案例創建一個函數(顯示價格),為Left案例創建另一個函數(顯示錯誤),然後使用它們創建Either Monad:

const showPrice = (total) => { console.log('Price: ' + total) }; 
const showError = (error) => { console.log('Error: ' + error.message); }; 
const eitherErrorOrPrice = RamdaFantasy.Either.either(showError, showPrice);

最後,只需要執行Monad來計算最終價格:

//計算出價值25的產品(含21%的增值稅和10%的折扣)的最終價格。
 eitherErrorOrPrice(
   RamdaFantasy.Either.Right(25)
     .chain(withTaxes(0.21))
     .chain(withDiscount(0.1))
)

結論:JavaScript中的函數式編程

正如我們所看到的,一旦用Maybe和Either單子分解了代碼,就沒有那麼複雜了。如果使用得當,它們可以使我們的代碼更易於閱讀和維護。

唯一的不便是我們需要克服的初始障礙,但這可以通過在網上一些示例並進行一些測試來完成。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/209076.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-08 15:24
下一篇 2024-12-08 15:24

相關推薦

發表回復

登錄後才能評論