Jun 01, 2021 Article blog
JavaScript
is a popular programming language, and this article was compiled today to give you a deeper understanding of
JavaScript
Let me show you some examples of
how to apply functional programming in JavaScript.
Even though functional programming can greatly improve your application's code, its principles can be challenging at first. Because explaining all of this in detail will take a lot of time, we decided to use two actual code samples to cover these concepts.
In the first example, we found a way to avoid verifying that the variable is
Null
Suppose in our application, we can find users with the following format:
const someUser = {
name: 'some_name',
email: '[email protected]',
settings: {
language: 'sp'
}
};
There is a feature that returns welcome messages in the language set by the user.
const allGreetings = {
'en': '嗨',
'sp': '你好',
'fr': '欢迎你'
};
const getGreetingForUser = (user) => {
//将要执行
}
Take a look at the implementation of a
getGreetingForUser
function that follows the imperative model:
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));
As you can see above, you must check whether the user already exists, if the language is set, and if you are ready to welcome the message. If there is a problem, we will return a message in the default language.
Now, let's look at the same function, but this time we'll use functional programming in its implementation:
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));
To handle situations that may be
null
or undefined, we will use
Maybe Monad
This allows us to create wrappers around objects and assign default behavior to empty objects.
Let's compare the two solutions:
//代替验证用户是否为空
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)
// 指定的默认值。
Maybe Monad
is useful when we know the default behavior when there is an empty error.
However, if we have a function that throws an error, or we link the various functions that throw the error together, and we want to know which one has failed, we can use
Either Monad
instead.
Now, let's assume that we're calculating the price of the product, taking into account both VAT and possible discounts. We already have the following code:
const withTaxes = (tax, price) => {
if (!_.isNumber(price)) {
return new Error("Price is not numeric");
}
return price + (tax * price);
};
const withDiscount = (dis, price) => {
if (!_.isNumber(price)) {
return new Error("Price is not numeric");
}
if (price < 5)
return new Error("Discounts not available for low-priced items");
}
return price - (price * dis);5
};
const isError = (e) => e && e.name === 'Error';
const calculatePrice(price, tax, discount) => {
//将要执行
}
Let's look at the implementation of a
calculatePrice
function that follows the imperative model:
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)
Now let's learn how to override this function with
Either Monad
There are two constructors,
Left
and
Right
What we're going to do is store exceptions to
Left
constructor and normal results (happy paths) to the
Right
constructor.
First, the existing
withTaxes
and
withDiscount
are changed so that they return
Left
in the event of an error and
Right
in all normal cases:
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));
});
We then create a function for the
Right
case (show price), another function for
Left
case (display error), and then use them to create
Either Monad
const showPrice = (total) => { console.log('Price: ' + total) };
const showError = (error) => { console.log('Error: ' + error.message); };
const eitherErrorOrPrice = RamdaFantasy.Either.either(showError, showPrice);
Finally, you only need to execute Monad to calculate the final price:
//计算出价值25的产品(含21%的增值税和10%的折扣)的最终价格。
eitherErrorOrPrice(
RamdaFantasy.Either.Right(25)
.chain(withTaxes(0.21))
.chain(withDiscount(0.1))
)
As we've seen, once you break down the code with
Maybe
and
Either
it's not that complicated.
When used properly, they can make our code easier to read and maintain.
The only inconvenience is the initial hurdle we need to overcome, but this can be done by some examples online and some testing.
These are examples of applying functional programming in
JavaScript
which I hope will help you.
Then students who want to learn
JavaScript
can click on the link below
JavaScript tutorial: https://www.w3cschool.cn/javascript/
JavaScript Microsyscope: https://www.w3cschool.cn/minicourse/play/jscourse
Source: www.toutiao.com/a6836176173207126541/