【问题标题】:Is it always enought to use !! to obtain the correct boolean value in Javascript总是够用吗!!在 Javascript 中获取正确的布尔值
【发布时间】:2019-08-12 19:56:12
【问题描述】:

我一直在审查一个看起来像这样的案例:

loggedInUser$ = this.select().pipe(
    filter(({ user }) => toBoolean(user)),
    map(({ user: { firstName: f, lastName: l } }) => `${f} ${l}`)
);

只是好奇我们是否总是可以用!! 代替这个方法来获得一个布尔值以及是否。 IIUC 的语义总是一样的?

换句话说,我们应该始终能够将toBoolean(...) 替换为!!

实现如下所示:

// @internal
export function toBoolean(value: any): boolean 
{
  return value != null && `${value}` !== 'false';
}

分析

因此,根据答案,区别在于!! 为“假”返回真,而toBoolean() 为“假”返回false

这有点主观,但我个人觉得告诉用户使用!! 比其他一些含糖的方法更好,因为我们应该先熟悉 Javascript 基础/语义,然后再从中构建。

因此,如果有人希望 'false' 为假,那么他们必须明确地实现它。在这种情况下,应用程序是某人的名字实际上是“假”,我们希望允许它为真。

【问题讨论】:

  • 除非您发布“Akita toBoolean”的实现(我从未听说过),否则我们无法判断它是否在语义上等同于 !!
  • 您应该始终根据问题的背景调整您的状况。我认为最好和更易读的解决方案是使用user && user.firstName && user.lastName
  • 将实现添加到问题中。
  • Akita 的toBoolean 实现检查值的字符串表示形式是否既不是null 也不是"false"。因此toBoolean("false")!!"false" 会有所不同,如this stackblitz 所示。

标签: javascript node.js angular typescript rxjs


【解决方案1】:

不,!! 不等于 toBoolean

为了进一步解释,!! 将始终返回布尔值 MDN 甚至还有关于 !! 用法的注释:

可以串联使用几个 NOT 运算符来显式强制将任何值转换为相应的布尔原语。转换基于值的“真实性”或“虚假性”(请参阅​​真实性和虚假性)。

同样的转换可以通过Boolean函数完成。

所以你总是可以用!!x替换Boolean(x),但是toBoolean呢?请注意toBoolean 将其参数转换为字符串并将其与字符串'false' 进行比较,因此至少有一种情况不一样:

function toBoolean(value: any): boolean 
{
  return value != null && `${value}` !== 'false';
}

console.log(Boolean('false'))
console.log(toBoolean('false'))

并显示一个更微妙的问题:

function toBoolean(value: any): boolean 
{
  return value != null && `${value}` !== 'false';
}

const foo = { toString: () => 'false' };

console.log(Boolean(foo))
console.log(toBoolean(foo))

【讨论】:

    【解决方案2】:

    不,您的 toBoolean!! 在语义上不等效。 toBoolean 依赖于字符串序列化,这是一种将值转换为布尔值的相当奇怪的方式。以下是一些导致不同结果的值:

    toBoolean(0) == true
    toBoolean('false') == false
    toBoolean('') == true
    toBoolean({toString(){return "false"}}) == false
    

    【讨论】:

    • 只是好奇,您认为一般情况下使用!! 更好吗?有人评论说这取决于“我的”用例……但秋田每周有 14K 的下载量,我个人认为人们可能会看到“假”应该为真的情况,尽管概率很低。使用 !! 解决了 IIUC。
    • @Ole 我认为没有一般规则。我宁愿根本不必使用任何演员表,而是立即获得传递的布尔值。如果您需要转换,则始终需要根据用例对其进行调整。在您的情况下,我会选择 filter(({ user }) => user != null && typeof user.firstName == "string" && typeof user.lastName == "string") 以更加安全,但根据您对输入数据的了解,您可能可以简化。
    • 谢谢,我也更喜欢这个!
    猜你喜欢
    • 2013-10-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多