У меня есть этот кусок кода (взят из этого вопроса ):
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err)
return done(err);
var pending = list.length;
if (!pending)
return done(null, results);
list.forEach(function(file) {
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending)
done(null, results);
});
} else {
results.push(file);
if (!--pending)
done(null, results);
}
});
});
});
};
Я пытаюсь следовать этому, и я думаю, что понимаю все, кроме как в конце, где говорится !--pending
. В этом контексте, что делает эта команда?
Изменить: Я ценю все дальнейшие комментарии, но вопрос был дан ответ много раз. Спасибо, в любом случае!
!~--[value] ^ true
Я называю такой код "безопасность работы"-->
оператора?Ответы:
!
инвертирует значение и дает противоположное логическое значение:--[value]
вычитает одно (1) из числа, а затем возвращает то число, с которым нужно работать:Таким образом,
!--pending
вычитает один из ожидающих, а затем возвращает противоположность его истинности / ложные значения (независимо от того, является ли он0
).И да, следуйте ProTip. Это может быть распространенной идиомой в других языках программирования, но для большинства декларативного программирования JavaScript это выглядит совершенно чуждо.
источник
--
действует только на переменные; Вы не можете применить его к значениям в целом.validSimpleAssignmentTarget
s, чтобы быть точным. Это включает ссылки на идентификаторы и ссылки на свойства.--0
и--1
не будет работать. Числовые литералы недопустимы в выражении левой стороныi > -1
чемi--
(и, кстати, ты забылi = init() - 1
). Вот для чего идиомы ... и каждый программист должен учить их.Это не специальный оператор, это два стандартных оператора один за другим:
--
)!
)Это приводит
pending
к уменьшению и проверке на нулевое значение.источник
if(pending === 1)
?if( pending === 1 ) { done... } else { pending = pending - 1; }
.Ряд ответов описывает, что делает эта команда, но не почему она выполняется именно здесь.
Я родом из мира C, и я читаю
!--pending
как «Обратный отсчетpending
и проверить, равен ли он нулю», не задумываясь об этом. Это идиома, которую, я думаю, должны знать программисты на похожих языках.Функция использует
readdir
для получения списка файлов и подкаталогов, которые я буду называть «записи».Переменная
pending
отслеживает, сколько из них осталось обработать. Он начинается как длина списка и ведет к нулю при обработке каждой записи.Эти записи могут быть обработаны не по порядку, поэтому необходимо вести обратный отсчет, а не просто использовать простой цикл. Когда все записи обработаны,
done
вызывается обратный вызов, чтобы уведомить первоначального абонента об этом факте.В первом обращении к
done
предваряетсяreturn
не потому, что мы хотим вернуть значение, а просто чтобы остановить выполнение функции в этой точке. Это был бы более чистый код, чтобы опуститьreturn
и поместить альтернативу вelse
.источник
!--pending
не справится со многими строчками и рекомендациями по стилю. Мне достаточно сказать, что это, вероятно, не идиоматично (независимо от того, является ли альтернатива «лучшей»).int
вbool
неявно и не имеют абсолютно никакого отношения к использованию!--
.Это стенография.
!
не является".--
уменьшает значение.Таким образом,
!--
проверяется, является ли значение, полученное в результате отрицания результата уменьшения значения, ложным.Попробуй это:
Первое ложно, так как значение x равно 1, второе истинно, так как значение x равно 0.
Примечание:
!x--
сначала проверит, является ли x ложным, а затем уменьшит его.источник
!
, в то время как предварительное исправление имеет более низкий приоритет. Приоритет JavaScript-оператораvar x = 2; console.log(!x--); console.log(!x--); console.log(!x--);
). Хотя пост-исправление--
может выполняться первым, его возвращаемое значение - это значение переменной перед уменьшением ( Decrement Opperator ).!--
возвращает отрицание результата уменьшения значения». Только внешний код, напримерconsole.log()
, проверяет, является ли его содержимое достоверным.!
оператор JavaScript НЕ--
является оператором перед декрементом. Так,источник
--
оператор мог работать с константой ... может, вы имели ввиду--x
вместо--0
?средства
средства
источник
if(0 == pending)
из-за потенциальных опечаток.if(0 = pending)
это синтаксическая ошибкаif(pending = 0)
является присваиванием, которое приведет к запутанному поведению в готовом коде.if(0 = pending)
это не синтаксическая ошибка - она хорошо разбирается - это ссылочная ошибка, потому что0
она не присваивается (см. ECMA-262 (6-е изд.) С. 12.14.1).Это оператор not, за которым следует предварительный декремент на месте.
Так что, если
pending
было целое число со значением 1:источник
Он просто уменьшается
pending
на единицу и получает свое логическое дополнение (отрицание). Логическое дополнение любого числа, отличного от 0false
, для 0 этоtrue
.источник
объяснение
Это 2 оператора, а
!
и--
Таким образом,
--
x уменьшается на 1, а затем!
возвращает true, если x теперь равно 0 (или NaN ...), и false, если это не так. Вы могли бы прочитать эту идиому что-то вроде "мы уменьшаем x и если это делает его нулевым ..."Если вы хотите сделать его более читабельным, вы можете:
Попробуйте это:
Скрипка (Попробуйте код)
источник
Настоящая проблема здесь заключается в отсутствии пробела между двумя операторами
!
и--
.Я не знаю, почему люди думают, что после
!
оператора нельзя использовать пробел . Я думаю, что это происходит из-за строгого применения механических правил пробела вместо здравого смысла. Почти все стандарты кодирования, которые я видел, запрещают пробелы после всех унарных операторов, но почему?Если когда-либо был случай, когда вам явно нужно это место, это одно.
Рассмотрим этот фрагмент кода:
Мало того, что
!
и--
пюрешься, ты тоже это(
ударил против них. Неудивительно, что сложно сказать, с чем это связано.Чуть больше пробелов делает код намного более понятным:
Конечно, если вы привыкли к механическим правилам, таким как «без пробела внутри паренсов» и «без пробела после унарного оператора», это может показаться немного чуждым.
Но посмотрите на то, как лишние пробелы группируют и разделяют различные части
if
оператора и выражения: у вас есть--pending
, так что--
, очевидно, он является собственным оператором и тесно связан с нимpending
. (Это уменьшаетpending
и возвращает уменьшенный результат.) Затем вы получили!
отделенное от этого, так что это, очевидно, отдельный оператор, сводящий на нет результат. Наконец, вы получилиif(
и)
окружите все выражение, чтобы сделать егоif
заявлением.И да, я удалил пространство между
if
и(
, так как(
принадлежит кif
. Это(
не часть какого-то(!--
синтаксиса, как кажется в оригинале,(
если часть синтаксиса самогоif
оператора.Пробелы здесь служат для передачи смысла , а не следуют некоторому стандарту механического кодирования.
источник
!--
это какой-то оператор javascript, которого я не знал. Почему бы не использовать скобки, чтобы сделать его еще более явным?if(!(--pending))
++
или--
, но многие действительно запрещают использовать несущественные пробелы, такие как!
оператор префикса, и несущественные скобки.