!
инвертирует значение и дает противоположное логическое значение:
!true == false
!false == true
!1 == false
!0 == true
--[value]
вычитает один (1) из числа, а затем возвращает то число, с которым нужно работать:
var a = 1, b = 2;
--a == 0
--b == 1
Таким образом, !--pending
вычитает одно из ожидающих, а затем возвращает значение, противоположное его значению истина / ложь (независимо от того, является ли оно 0
).
pending = 2; !--pending == false
pending = 1; !--pending == true
pending = 0; !--pending == false
И да, следуйте подсказке. Это может быть распространенной идиомой в других языках программирования, но для большинства декларативного программирования на JavaScript это выглядит довольно чуждо.
Это не специальный оператор, это два стандартных оператора один за другим:
--
) !
) Это приводит к тому, что значение pending
уменьшается, а затем проверяется на нулевое значение.
В ряде ответов описано , что делает эта команда, но не , почему она выполняется именно здесь.
Я родом из мира Си, и я читаю !--pending
как «обратный отсчет pending
и проверяю, равен ли он нулю», не задумываясь об этом. Это идиома, которую, я думаю, должны знать программисты на похожих языках.
Функция использует readdir
для получения списка файлов и подкаталогов, которые я буду называть «записи».
Переменная pending
отслеживает, сколько из них еще предстоит обработать. Он начинается как длина списка и отсчитывается до нуля при обработке каждой записи.
Эти записи могут быть обработаны не по порядку, поэтому необходим обратный отсчет, а не простой цикл. Когда все записи были обработаны, вызывается обратный вызов done
, чтобы уведомить первоначального абонента об этом факте.
В первом вызове done
добавляется return
не потому, что мы хотим вернуть значение, а просто для того, чтобы функция перестала выполняться в этой точке. Это был бы более чистый код, чтобы убрать return
и поместить альтернативу в else
.
Это сокращение.
!
"не".
--
уменьшает значение.
Таким образом, !--
проверяет, является ли значение, полученное в результате отрицания результата уменьшения значения, ложным.
Попробуйте это:
var x = 2;
console.log(!--x);
console.log(!--x);
Первое значение false, поскольку значение x равно 1, второе значение true, поскольку значение x равно 0.
Примечание: !x--
сначала проверит, является ли x ложным, а затем уменьшит его.
!
- это оператор JavaScript NOT
--
- оператор перед декрементом. Итак,
x = 1;
if (!x) // false
if (!--x) // becomes 0 and then uses the NOT operator,
// which makes the condition to be true
if(!--pending)
означает
if(0 == --pending)
означает
pending = pending - 1;
if(0 == pending)
Он просто уменьшается pending
на единицу и получает свое логическое дополнение (отрицание). Логическим дополнением любого числа, отличного от 0, является false
, для 0 - true
.
Это 2 оператора, a !
и a --
!--x
Итак, это ухудшает x на 1 и проверяет, является ли это логическим значением.
Если вы хотите сделать его более читабельным, вы можете:
var x = 1
x = x - 1
if(!x){ //=> true
console.log("I understand `!--` now!")
}
x //=> 0
/* This is an example of the above, you can read this, but it is not needed for !-- */function interactive(a){$("span.code").keydown(function(e){if(13==(e.keyCode||e.which)){var t=$(this);t.clone().html("code").insertAfter(t.next().next()).show().focus().after(template.clone().removeClass("result-template").show()).next().after("<br>"),interactive(),e.preventDefault()}}).keyup(function(e){13!=(e.keyCode||e.which)&&run()})}var template=$(".result-template").hide(),code=$("span.code");code.attr("contenteditable","true").each(function(e,t){template.clone().removeClass("result-template").insertAfter(t)}),interactive(),$.fn.reduce=[].reduce;function run(){var b=!1,context={};$("span.code").each(function(){var a=$(this),res=a.next().show().removeClass("error");try{with(context)res.html(b?"":" //=> "+eval(a.text()))}catch(e){b=e,res.html(" Error: "+b.message).addClass("error")}})};run();
/* This is an example of the above, you can read this, but it is not needed for !-- */span.result.error{display:block;color:red}.code{min-width:10px}body{font-family:Helvetica,sans-serif}
<!-- This is an example of the above, you can read this, but it is not needed for `!--` --><span class="result result-template"> //=> unknown </span> <h2>Edit This Code:</h2><code><span class="code">x = 1</span><br><span class="code">!--x</span><br><span class="code"> x </span><br></code> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Это оператор not, за которым следует предварительный декремент на месте.
Так что, если pending
было целым числом со значением 1:
val = 1;
--val; // val is 0 here
!val // evaluates to true
Настоящей проблемой здесь является отсутствие пробела между двумя операторами !
и --
.
Я не знаю, почему люди думают, что после оператора !
нельзя использовать пробел. Я думаю, что это происходит из-за строгого применения механических правил пробела вместо здравого смысла. Почти все стандарты кодирования, которые я видел, запрещают пробелы после всех унарных операторов, но почему?
Если когда-либо был случай, когда вам явно нужно это пространство, это один.
]Рассмотрим этот фрагмент кода:
if (!--pending)
done(null, results);
Мало того, что !
и --
смешиваются вместе, у вас также есть (
, чтобы ударить их. Неудивительно, что трудно сказать, что с чем связано.
Чуть больше пробелов делает код намного более понятным:
if( ! --pending )
done( null, results );
Конечно, если вы привыкли к механическим правилам, таким как «без пробела внутри паренсов» и «без пробела после унарного оператора», это может показаться немного чужим.
Но посмотрите, как лишние пробелы группируют и разделяют различные части выражения и выражения if
: у вас есть --pending
, поэтому --
явно является своим собственным оператором и тесно связан с pending
. ]. (Он уменьшает pending
и возвращает уменьшенный результат.) Затем вы отделили !
от этого, так что это, очевидно, отдельный оператор, сводящий на нет результат. Наконец, у вас есть if(
и )
, окружающие все выражение, чтобы сделать его выражением if
.
И да, я убрал пробел между if
и (
, потому что (
принадлежит к if
. Этот (
не является частью какого-то синтаксиса (!--
, как кажется в оригинале, а часть (
- синтаксиса самого оператора if
.
Пробелы здесь служат для передачи значения вместо того, чтобы следовать какому-либо механическому стандарту кодирования.