Я хотел бы знать, есть ли в JavaScript оценка «короткого замыкания», такая как && Operator в C #. Если нет, я хотел бы знать, есть ли обходной путь, который имеет смысл принять.
Я хотел бы знать, есть ли в JavaScript оценка «короткого замыкания», такая как && Operator в C #. Если нет, я хотел бы знать, есть ли обходной путь, который имеет смысл принять.
Ответы:
Да, JavaScript имеет оценку «короткого замыкания».
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-circuit
с этим логическим оператором. Просто попробуйте сами. Воспользуйтесь моей демонстрацией.
Этот ответ очень подробно описывает, как короткое замыканиеработает в JavaScript, со всеми подводными камнями, а также соответствующими темами, такими как приоритет операторов, если вы ищете быстрое определение и уже понимаете, как работает короткое замыкание, я бы рекомендовал проверить другие ответы.
Сначала давайте проверим поведение, с которым мы все знакомы, внутри if()
блока, где мы используем, &&
чтобы проверить, есть ли две вещи true
:
if (true && true) {
console.log('bar');
}
Теперь ваш первый инстинкт, вероятно, скажет: «Ах, да, довольно просто, код выполняет оператор, если оба expr1
и expr2
оцениваются как true
»
Ну да и нет. Вы технически правы, это поведение, которое вы описали, но это не совсем то, как оценивается код, и нам нужно вникнуть глубже, чтобы полностью понять.
&&
и ||
интерпретированы ?:Пора заглянуть "под капот" javascript двигатель ". Рассмотрим этот практический пример:
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);
Ну результат 260
... но почему? Чтобы получить ответ, нам нужно понять, как работает оценка короткого замыкания.
По определению MDN
&&
операторexpr1 && expr2
выполняется followingly:Если
expr1
можно преобразовать вtrue
, возвращаетexpr2
; иначе возвращаетсяexpr1
.
Это означает, что в нашем практическом примере, const res
оценивается следующим образом:
expr1
-sanitise(0xFF)
0xFF
является допустимым шестнадцатеричным числом для 250, иначе я бы вернулся NaN
expr1
Возвратил «truthy» значение, время выполнения expr2
( в противном случае я бы остановить , как NaN
это falsy)userinput
это правда (число), я могу добавить +5
к немуТаким образом, здесь мы смогли избежать дополнительных if
блоков и дальнейших isNaN
проверок с помощью простого использования &&
оператора.
К настоящему моменту мы должны хотя бы представить себе, как короткое замыканиеоператоры работают. Универсальное правило гласит:
(some falsy expression) && expr
будет оценивать ложное выражение(some truthy expression) || expr
будет оценивать правдивое выражениеВот еще несколько примеров для лучшего понимания:
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');`
*/
Отлично, надеюсь, вы уже освоились! Последнее, что нам нужно знать, это правило приоритета операторов, а именно:
&&
Оператор всегда выполняется до ||
оператора.Рассмотрим следующий пример:
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
Это вернет as, что, возможно, сбивает с толку некоторых as a()
. Причина очень проста, это просто наше зрение обманывает нас, потому что мы привыкли читать слева направо. Давайте возьмем то, console.log()
что нельзя, и сосредоточимся исключительно на оценке
true || false && false
Теперь, чтобы обдумать это:
Мы сказали, что &&
оператор имеет приоритет, поэтому он оценивается как первый. Чтобы лучше представить себе оценку, придумайте определение
expr1 && expr2
Куда:
expr2
является false
expr1
является true || false
Итак, это была сложная часть, теперь true || false
она оценивается ( expr1
- левая часть &&
).
||
оператор прекращает выполнение, если expr1 || expr2
in expr1
оценивается как истинное, expr1
выполняется и выполнение кода останавливается.Возвращаемое значение true
Что ж ... это было довольно сложно из-за нескольких странных правил и семантики. Но помните, что вы всегда можете избежать приоритета оператора с помощью ()
- точно так же, как в математике
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()
*/
expr1
и expr2
или condition1
или независимо от того , что это просто заблуждение. Во-первых, вы можете ввести локальные переменные, например. const expr1 = true; if(expr1 && ...)
https://www.google.com/search?q=site:stackoverflow.com+%s
в качестве ярлыка поиска (Chrome / Firefox) для ускорения поиска.