Je voudrais savoir si JavaScript a une évaluation "court-circuit" comme && Operator en C #. Sinon, j'aimerais savoir s'il existe une solution de contournement qui a du sens à adopter.
Je voudrais savoir si JavaScript a une évaluation "court-circuit" comme && Operator en C #. Sinon, j'aimerais savoir s'il existe une solution de contournement qui a du sens à adopter.
Réponses:
Oui, JavaScript a une évaluation "court-circuit".
if (true == true || foo.foo){
// Passes, no errors because foo isn't defined.
}
if (false && foo.foo){
// Passes, no errors because foo isn't defined.
}
Short-circuitavec cet opérateur logique. Essayez-le vous-même. Utilisez ma démo.
Cette réponse explique en détail comment court-circuit fonctionne en JavaScript, avec tous les goûts et thèmes pertinents tels que la priorité des opérateurs, si vous recherchez une définition rapide et que vous comprenez déjà le fonctionnement du court-circuit, je vous recommande de vérifier d'autres réponses.
Commençons par inspecter le comportement que nous connaissons tous, à l'intérieur du if()bloc, où nous utilisons &&pour vérifier si les deux choses sont true:
if (true && true) {
console.log('bar');
}
Maintenant, votre premier instinct est probablement de dire: 'Ah oui, assez simple, le code exécute l'instruction si les deux expr1et expr2sont évalués comme true'
Eh bien, oui et non. Vous avez techniquement raison, c'est le comportement que vous avez décrit, mais ce n'est pas exactement ainsi que le code est évalué et nous devrons approfondir afin de bien comprendre.
&&et ||?:Il est temps de regarder "sous le capot du javascript engine ". Prenons cet exemple pratique:
function sanitise(x) {
if (isNaN(x)) {
return NaN;
}
return x;
}
let userinput = 0xFF; // as an example
const res = sanitise(userinput) && userinput + 5
console.log(res);
Eh bien, le résultat est 260... mais pourquoi? Afin d'obtenir la réponse, nous devons comprendre comment fonctionne l'évaluation des courts-circuits.
Par la définition MDN, l'
&&opérateur dansexpr1 && expr2est exécuté comme suit:Si
expr1peut être converti entrue, retourneexpr2; sinon, revientexpr1.
Cela signifie donc, dans notre exemple pratique, que le const resest évalué de la manière suivante:
expr1-sanitise(0xFF)0xFF est un nombre hexadécimal valide pour 250, sinon je retournerais NaNexpr1renvoyé une valeur "véridique", temps d'exécution expr2 (sinon je m'arrêterais comme NaNfaux)userinputest truthy (un numéro), je peux ajouter +5à ce
- «Truthy» signifie que l'expression peut être évaluée comme vraie. Voici une liste d' expressions véridiques et fausses .
Donc ici, nous avons pu éviter des ifblocages supplémentaires et des isNaNcontrôles supplémentaires avec une simple utilisation de l' &&opérateur.
À présent, nous devrions au moins avoir une image de la façon dont le court-circuitles opérateurs travaillent. La règle universelle va:
(some falsy expression) && expr évaluera une expression erronée(some truthy expression) || expr évaluera l'expression de la véritéVoici quelques exemples supplémentaires pour une meilleure compréhension:
function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }
if ( a() && b() ){
console.log('foobar');
}
//Evaluates a() as false, stops execution.
function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }
if ( a() || b() ){
console.log('foobar');
}
/* 1. Evaluates a() as false
2. So it should execute expr2, which is `b()`
3. b() returned as true, executing statement `console.log('foobar');`
*/
Bien, j'espère que vous comprenez le coup! La dernière chose que nous devons savoir est une règle sur la priorité des opérateurs, à savoir:
&&opérateur est toujours exécuté avant l' ||opérateur.Prenons l'exemple suivant:
function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}
console.log(a() || b() && c());
// returns a() and stops execution
Cela reviendra comme, peut-être déroutant pour certains a(). La raison est assez simple, c'est juste notre vue qui nous trompe, parce que nous avons l'habitude de lire de gauche à droite. Prenons le console.log()et ce qui ne l'est pas et concentrons-nous uniquement sur l'évaluation
true || false && false
Maintenant, pour comprendre ceci:
Nous avons dit que l' &&opérateur a la priorité, donc il est évalué comme premier. Pour nous aider à mieux imaginer l'évaluation, pensez à la définition
expr1 && expr2
Où:
expr2 est falseexpr1 est true || falseC'était donc la partie délicate, maintenant true || falseest évaluée (le expr1- côté gauche de la &&).
||opérateur arrête l'exécution si expr1 || expr2in est expr1évalué comme véridique, le expr1est exécuté et l'exécution du code s'arrête.La valeur renvoyée est true
Eh bien… c'était assez délicat, tout cela à cause de quelques règles et sémantiques étranges. Mais rappelez-vous que vous pouvez toujours échapper à la priorité des opérateurs avec ()- comme en maths
function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}
console.log((a() || b()) && c());
/* 1. The () escape && operator precedence
2. a() is evaluated as false, so expr2 (c()) to be executed
3. c()
*/
expr1et expr2 ou condition1ou de quoi que ce soit, c'est juste déroutant. Choisissez-en un, vous pouvez également introduire des variables locales, par exemple. const expr1 = true; if(expr1 && ...)
https://www.google.com/search?q=site:stackoverflow.com+%sun raccourci de recherche (Chrome / Firefox) pour accélérer les recherches.