【问题标题】:&& operator and execution when boolean function returns false&& 运算符和布尔函数返回 false 时的执行
【发布时间】:2012-12-06 02:11:32
【问题描述】:

我不理解 javascript 的行为。

我正在对 jquery ui 对话框进行表单验证。看来这是一个javascript问题,而不是jquery问题。

为了验证,我为每个返回 true 或 false 的字段执行一个函数,并且一个布尔变量接收连续 && 运算符的结果。像这样:

bValid = checkRegexp(validite, /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/, "Entrez la date de validit\350 sous la forme JJ/MM/AAAA." );
bValid = bValid && checkLength(libelle, "Libell\351", 1, 100 );
bvalid = bValid && checkLength(description, "Description", 1, 250);

以下是验证函数:

function checkLength( o, n, min, max ) {
    if ( o.val().length > max || o.val().length < min ) {
        o.addClass( "ui-state-error" );
        if(o.val().length == 0) { textError = textError + "le champ " + n + " est requis !\n"; }
        else { textError = textError + "Taille de " + n + " entre " + min + " et " + max + "caract\350res.\n"; }
        return false;
    } else {
        return true;
    }
}

function checkRegexp( o, regexp, n ) {
     if (!(regexp.test(o.val()))) {
         o.addClass( "ui-state-error" );
         textError = textError + n + "\n";
         return false;
     } else {
         return true;
     }
}

预期的行为是所有函数都被执行,并且所有错误的字段都被标记为错误,并带有错误消息的串联。作为信息,bValid 变量包含连续 && 运算符的布尔结果。最后一点有效;没问题。

真正的行为是,当函数返回false 时,似乎没有执行以下函数。结果是只有第一个遇到的错误字段被标记为错误。

为什么?

【问题讨论】:

  • 经过多次思考,我明白了为什么:Javascript必须思考:“为什么要执行一个不会改变最终结果的函数?”如果 'bValid' 已经为假,在 && 之后执行函数是没有用的,因为结果不会改变 'bvalid' 的值!如果程序员想要申请,因为还有其他结果要申请,愚蠢的 JAVASCRIPT ????我不问你的意见!对不起,但我现在好多了……哈哈
  • 为了解决这个问题,我选择使用数字返回值:它就像一个魅力...... ^_^

标签: javascript operators


【解决方案1】:

这叫做短路。 &amp;&amp; 在逻辑上可以被认为是一种“and-also”语法,如果第一个表达式失败,则不计算第二个表达式。如果您希望处理第二个表达式而不考虑第一个表达式,您可以考虑颠倒它们的顺序或尝试:

bValid = bValid & checkLength(description, "Description", 1, 250);

虽然,这在功能上等同于

bValid = checkLength(description, "Description", 1, 250);

【讨论】:

  • 我认为这只是一个错字,但它的&amp;&amp; 不是&amp;,在这种情况下它们不等价,因为它们使用的是bvalid 上一行的真值
  • @HunterMcMillen:什么是错字?
  • 第一行只有一个 & 号而不是两个,这意味着按位与。
  • @HunterMcMillen:你误读了我的回答。我建议他使用按位比较(不会短路)而不是标准比较。由于这两个表达式都是布尔值,所以比较会相当简单,但按位比较应该像我上面描述的那样。
【解决方案2】:

因为&amp;&amp; 运算符是“短路的”。这意味着由于编译器/解释器/任何东西都知道&amp;&amp; 运算符的两侧操作数必须为真,如果第一个为假,则第二个不会被执行。

如果你想让你的函数确定执行,只需将操作数的顺序交换为&amp;&amp;

bValid = checkRegexp(validite, /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/, "Entrez la date de validit\350 sous la forme JJ/MM/AAAA." );
bValid = checkLength(libelle, "Libell\351", 1, 100 )     && bValid;
bvalid = checkLength(description, "Description", 1, 250) && bValid

【讨论】:

  • 谢谢!!我选择数值,但同时我也假设您的解决方案。使用数值,我可以计算错误并根据数量或错误更改对话框 dox 的高度。但是,&amp;&amp; 操作员的行为一开始就完全奇怪。
【解决方案3】:

因为 Javascript 会简化和“优化”...如果双重 &amp;&amp; 操作的第一个操作数已经为假,结果肯定是假的,因此它不会执行第二部分。

【讨论】:

    【解决方案4】:

    让我们用实际输出来改写它:

    bValid = checkRegexp(validite, /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/, "Entrez la date de validit\350 sous la forme JJ/MM/AAAA." );
    bValid = bValid && checkLength(libelle, "Libell\351", 1, 100 );
    bvalid = bValid && checkLength(description, "Description", 1, 250);
    
    false = checkRegexp(validite, /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/, "Entrez la date de validit\350 sous la forme JJ/MM/AAAA." );
    bValid = false && checkLength(libelle, "Libell\351", 1, 100 );
    bvalid = false && checkLength(description, "Description", 1, 250);
    

    当它达到 false 时,它​​将停止执行该条件。

    【讨论】:

    • 是的!我不知道这种行为,这是由于优化。交换操作数是成功的,因为第一个操作数总是被执行。谢谢你的回答!
    【解决方案5】:

    JavaScript 使用short circuit evaluation。即假 AND 任何东西总是假的,那么为什么还要进行第二次计算呢?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多