Javascript 重构复杂if表达式的最佳方法
我刚刚参加了一个大型电子商务项目,该项目有一个angularJS前端。我的任务是为结帐页面添加许多复杂的功能。。。已经有很多复杂的逻辑 为了让事情变得更难,我不断遇到许多类似下面的Javascript 重构复杂if表达式的最佳方法,javascript,angularjs,if-statement,expression,Javascript,Angularjs,If Statement,Expression,我刚刚参加了一个大型电子商务项目,该项目有一个angularJS前端。我的任务是为结帐页面添加许多复杂的功能。。。已经有很多复杂的逻辑 为了让事情变得更难,我不断遇到许多类似下面的if语句表达式,这使得它很难理解,而且使用许多此类if表达式来处理这些代码是一个缓慢的过程 其中一些表达非常关键,有时甚至更长。。。没有单元测试,当我问其他开发人员这是在检查什么以及为什么(为了确保我理解),我通常会被指向其他人而不是解释 if ((!previousBillingAddress) || (previo
if
语句表达式,这使得它很难理解,而且使用许多此类if
表达式来处理这些代码是一个缓慢的过程
其中一些表达非常关键,有时甚至更长。。。没有单元测试,当我问其他开发人员这是在检查什么以及为什么(为了确保我理解),我通常会被指向其他人而不是解释
if ((!previousBillingAddress) || (previousBillingAddress && previousBillingAddress.id !== bag.paymentAddress.id)){
console.log('all of the above was true'); // just a dummy log
} else {
console.log('all of the above was false'); // just a dummy log
}
有人有重构这些类型表达式的好技巧吗
我想把它们分解成具有描述性名称的函数,这些函数可以返回
true
或false
,但我不确定是否有更好的方法。您可以在|
的第二个操作数中删除以前的BillingAddress&
部分-您已经有了estblished以前的BillingAddress
不正确。这将使整个情况变得更糟
if (!previousBillingAddress || previousBillingAddress.id !== bag.paymentAddress.id) {
console.log('all of the above was true'); // just a dummy log
} else {
console.log('all of the above was false'); // just a dummy log
}
这对我来说足够短了。如果没有,则创建一个适当命名的助手函数,将
上一个BillingAddress
和包传递给该函数。您可以删除上一个BillingAddress&&
部分-在|
的第二个操作数中,您已经知道上一个BillingAddress
不是错误的。这将使整个情况变得更糟
if (!previousBillingAddress || previousBillingAddress.id !== bag.paymentAddress.id) {
console.log('all of the above was true'); // just a dummy log
} else {
console.log('all of the above was false'); // just a dummy log
}
这对我来说足够短了。如果没有,则创建一个适当命名的助手函数,向其传递先前的BillingAddress
和包
类似的内容
var billingId = previousBillingAddress && previousBillingAddress.id;
if (billingId || billingId === bag.paymentAddress.id){
console.log('all of the above was false'); // just a dummy log
} else {
console.log('all of the above was true'); // just a dummy log
}
我所做的
由于您使用的是if
和else
,因此在if语句中使用否定不是一种好的做法。所以我把它去掉了
如果您只想要被否定的部分(没有else)
&&将返回第一个false或最后一个true值。因此billingId
将等于false
或id
。在此基础上,您的第一个if将检查它的“false”
是否继续,因此您也可以使用相同的变量
像这样的
var billingId = previousBillingAddress && previousBillingAddress.id;
if (billingId || billingId === bag.paymentAddress.id){
console.log('all of the above was false'); // just a dummy log
} else {
console.log('all of the above was true'); // just a dummy log
}
我所做的
由于您使用的是if
和else
,因此在if语句中使用否定不是一种好的做法。所以我把它去掉了
如果您只想要被否定的部分(没有else)
&&将返回第一个false或最后一个true值。因此billingId
将等于false
或id
。在此基础上,您的第一个if将检查它的“false”
是否继续,因此您也可以使用相同的变量
评论是我们最好的朋友。您希望确保下一个查看代码的人确切地知道它应该做什么,并且从中可以更快、更容易地看到它到底在做什么
在这种情况下,可以缩短if语句中的表达式。这是我几乎用伪代码方法对其进行评论的方式:
// we need to check if the user has, and is using, a previous billing address
if (previousBillingAddress && previousBillingAddress.id === bag.paymentAddress.id)){
// the user is using a previous billing address
// do some work with the previous billing address
} else {
// the user is using a new address
// do some work with the new address
// save the new billing address
}
请注意,previousBillingAddress
是此if语句的主要主题。如果我们正在检查previousBillingAddress,那么在我们的第一个块中,我们希望确保处理如果我们有以前的账单地址会发生的情况。这样更合乎逻辑
如果我们没有以前的账单地址,那么检查一下,如果我们有账单地址,我们该怎么办就没有意义了
看这是多么干净和合乎逻辑 评论是我们最好的朋友。您希望确保下一个查看代码的人确切地知道它应该做什么,并且从中可以更快、更容易地看到它到底在做什么
在这种情况下,可以缩短if语句中的表达式。这是我几乎用伪代码方法对其进行评论的方式:
// we need to check if the user has, and is using, a previous billing address
if (previousBillingAddress && previousBillingAddress.id === bag.paymentAddress.id)){
// the user is using a previous billing address
// do some work with the previous billing address
} else {
// the user is using a new address
// do some work with the new address
// save the new billing address
}
请注意,previousBillingAddress
是此if语句的主要主题。如果我们正在检查previousBillingAddress,那么在我们的第一个块中,我们希望确保处理如果我们有以前的账单地址会发生的情况。这样更合乎逻辑
如果我们没有以前的账单地址,那么检查一下,如果我们有账单地址,我们该怎么办就没有意义了
看这是多么干净和合乎逻辑 在我个人看来,我认为您可以重构并封装函数内部的验证/检查,然后如果相同的验证适用于代码的其他部分(文件/模块等),您可以重用它。在本例中,您使用的是angular,因此最好使用angular定制服务进行这种类型的业务验证,因为它们也可以操作范围在我个人看来,我认为您可以在函数内部重构和封装验证/检查,然后如果相同的验证适用于代码的其他部分(文件/模块/etc…),您可以重用它。在这种情况下,您使用的是angular,因此最好使用angular定制服务进行这种类型的业务验证,因为它们还可以操纵范围
A = previousBillingAddress
B = previousBillingAddress.id !== bag.paymentAddress.id
那么你的表达是:
if (!A || (A && B)) {
log1
} else {
log2
}
我们能用!A | | |(A&B)
?它等于!A | | B
:
A | B | !A | A && B | !A || (A && B) | !A || B
==========================================================
1 | 1 | 0 | 1 | 1 | 1
1 | 0 | 0 | 0 | 0 | 0
0 | 1 | 1 | 0 | 1 | 1
0 | 0 | 1 | 0 | 1 | 1
这就是为什么您的表达式等于:
if (!previousBillingAddress || previousBillingAddress.id !== bag.paymentAddress.id) {
console.log('all of the above was true'); // just a dummy log
} else {
console.log('all of the above was false'); // just a dummy log
}
TL;DR
上表仅用于检查!A | |(A和&B)
是否等于!A | | B
。如何猜测!A | | B
?对于此类表达式,最好遵循以下规则:
A == !(!(A)) (rule 1)
!(A && B) == !A || !B (rule 2)
!(A || B) == !A && !B (rule 3)
A && (B || C) == A && B || A && C (rule 4)
所以我们有!A | |(A&&B)
,让我们玩吧。根据规则1,它等于
!(!(!A || (A && B)))
现在我们使用规则3:
!(!(!A || (A && B))) == !(A && !( A && B))
规则2:
!(A && !( A && B)) == !(A && (!A || !B)) (*)
由于第4条:
A && (!A || !B) == (A && !A) || (A && !B)
我们有
var weakPrevBillingAddress =
!previousBillingAddress ||
(previousBillingAddress &&
(previousBillingAddress.id !== bag.paymentAddress.id));
if (weakPrevBillingAddress) {
console.log('judged weak previousBillingAddress');
// other processing expected here
} else {
console.log('judged strong previousBillingAddress');
// other processing expected here
}
var weakPrevBA = !prevBA ||
(prevBA.id !== bag.paymentAddress.id);