Javascript 布尔逻辑(将 double bang 与 truthy/falsy 值进行比较)

Javascript boolean logic (comparing double bang with truthy/falsy values)

我正在检查一些代码,我发现了 运行 由 Javascript 退伍军人提供的东西。我对 Javascript 感到很自在,但我总是设法 运行 进入一些让我说,“我不知道 Javascript!”

我希望这是其中一种情况:

if (this.props.referralId != prevProps.referralId ||
    this.props.referralValidationStatus != prevProps.referralValidationStatus ||
    this.props.customerName != prevProps.customerName &&
    !!prevProps.personId != !this.props.personId) {
   // perform whatever logic is here...
}

我的问题:

  1. JS知道如何自动识别||的混合吗和 &&?或者此代码是否缺少 || 周围的括号比较?
  2. 正如所解释的那样 here,这是否公平?我是否应该期待将布尔值与 truthy/falsy 值进行比较时的明显行为?

我对这里的逻辑感到困惑。如果我要重写这个,我会这样做:

if ((this.props.referralId !== prevProps.referralId ||
    this.props.referralValidationStatus !== prevProps.referralValidationStatus ||
    this.props.customerName !== prevProps.customerName)
    && (!!prevProps.personId === !!this.props.personId)) {
   // Perform logic
}

但是,我想确认并确保我没有遗漏关于 JS 的一些东西。

提前感谢您确认我的直觉或在 JS 方面对我进行一些新的教育。期待您的评论and/or答案。

  1. 与大多数语言一样,Javascript 中有一个优先规则。 &&|| 之前计算,如您所见 here。所以,如果你需要检查所有的ors,然后用最后的结果来制作and,你是对的!使用括号。

  2. 你对 !! 重构也是正确的:

!!prevProps.personId != !this.props.personId

等同于:

!!prevProps.personId === !!this.props.personId

换句话说,它正在检查 prevProps.personIdthis.props.personId 是否都具有某个值(作为布尔值评估为 True),或者两者是否都是 empty/undefined/Nan (作为布尔值评估为 False ).

第一条语句说(伪代码):

if (
    //the first statement returns truthy
    this.props.referralId != prevProps.referralId ||

    // or the second statement returns truthy
    this.props.referralValidationStatus != prevProps.referralValidationStatus ||

    // or the combination of the third and fourth statements returns truthy
    this.props.customerName != prevProps.customerName 
    && 
    !!prevProps.personId != !this.props.personId
   )
   
   // then...

   {
   // perform whatever logic is here
   }

你的重写版本说(伪代码):

if (
    // one of these three statements is truthy
    (this.props.referralId !== prevProps.referralId ||
    this.props.referralValidationStatus !== prevProps.referralValidationStatus ||
    this.props.customerName !== prevProps.customerName)

    && // AND!

    // this statement also evaluates truthy
    (!!prevProps.personId === !!this.props.personId)
  ) 

    // then...

   {
   // perform whatever logic is here
   }

希望这能解释代码块之间的差异。

@rafaelodon 在其他方面是正确的