简体   繁体   中英

&& operator and execution when boolean function returns false

I don't understand a behavior of javascript.

I'm doing a form validation of a jquery ui dialog. It seems then it's a javascript issue, not a jquery issue.

For the validation, I execute a function per fields that return true or false and a boolean variable recieve the result of successive && operator. Like this :

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);

Here are, for information, the validation functions :

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;
     }
}

The behavior expected is that all the functions are executed and all the wrong fields are marked wrong with a concatenation of the error messages. For information, the bValid variable contains the boolean result of the successive && operators. This last point works ; no problemo.

The real behavior is that when a function return false , the following functions don't seem to be executed. The result is that only the first wrong field met is marked wrong.

Why ?

Because the && operator is 'short-circuited'. Meaning that since the compiler/interpreter/whatever knows that both sides operands for the && operator have to be true, if the first one is false then the second does not get executed.

If you want your function to execute for sure, just swap the order of the operands for && :

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

JavaScript uses short circuit evaluation . ie false AND anything is always false, so why bother doing the 2nd computation?

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

It's called short-circuiting. The && can be considered logically as an "and-also" syntax where the second expression is not evaluated if the first expression fails. If you want the second expression to process regardless of the first, you may consider reversing their order or trying:

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

Although, that is functionally equivalent to

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

Let's reword this with actual output:

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);

The moment it hits false it'll stop executing that conditional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM