Что значит "!--" в JavaScript?



у меня есть этот кусок кода (взятый из этого вопроса):



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. В этом контексте, что делает эта команда?



Edit: я ценю все дальнейшие комментарии, но на этот вопрос был дан ответ много раз. Все равно спасибо!

346   10  

10 ответов:

! инвертирует значение и дает вам противоположное логическое значение:

!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 с программирование это выглядит довольно чуждо.

Это не специальный оператор, это 2 стандартных оператора один за другим:

  1. префиксного декремента (--)
  2. логическое не (!)

Это приводит к pending для уменьшения, а затем проверить, если это ноль.

ряд ответов описывает что эта команда делает, а не почему это делается таким образом здесь.

Я пришел из мира С, и я читаю !--pending как "отсчет pending и проверить, если он равен нулю", не задумываясь об этом. Это идиома, которую я думаю, что программисты на подобных языках должны знать.

функция использует readdir получить список файлов и подкаталогов, которые я буду обобщенно называть "записи".

переменная pending отслеживает, сколько из них остается для обработки. Он начинается с длины списка и отсчитывается вниз к нулю по мере обработки каждой записи.

эти записи могут быть обработаны не по порядку, поэтому необходимо вести обратный отсчет, а не просто использовать простой цикл. Когда все записи были обработаны обратный вызов done вызывается для уведомления вызывающего этой факт.

в первом вызове done начинается с return, не потому, что мы хотим вернуть значение, а просто заставить функцию прекратить выполнение в этот момент. Это был бы более чистый код, чтобы удалить return и поставить альтернативу в else.

Это стенографировать.

! "нет".

-- уменьшает значение.

так !-- проверяет, является ли значение, полученное в результате отрицания результата уменьшения значения, ложным.

попробуйте это:

var x = 2;
console.log(!--x);
console.log(!--x);

первый является ложным, так как значение x равно 1, второй является истинным, так как значение x равно 0.

Примечание: !x-- сначала проверит, является ли x ложным, а затем уменьшит его.

! Это JavaScript не оператор

-- является оператором предварительного декремента. Итак,

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 было целое число со значением 1:

val = 1;
--val; // val is 0 here
!val // evaluates to true

объяснение

это 2 оператора, 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>

Скрипка (Попробуйте Код)

Он просто уменьшается pending и получает свое логическое дополнение (отрицание). Логическим дополнением любого числа, отличного от 0, является false, для 0 это true.

реальная проблема здесь заключается в отсутствии пространства между двумя операторами ! и --.

я не знаю, почему люди получают это в головы, что вы никогда не можете использовать пробел после ! оператора. Я думаю, что это происходит от жесткого применения механических правил пробелов вместо здравого смысла. Почти каждый стандарт кодирования, который я видел, запрещает пробелы после всех унарных операторов, но почему?

если бы был когда-нибудь случай, когда вы четко нужно это пространство, это одно.

рассмотрим следующий фрагмент кода:

if (!--pending)
    done(null, results);

не только ! и -- пюре вместе, у вас есть что ( врезался в них тоже. Неудивительно, что трудно сказать, что с чем связано.

немного больше пробелов делает код гораздо более ясным:

if( ! --pending )
    done( null, results );

конечно, если вы привыкли к механическим правилам, таким как" нет места внутри parens "и" нет места после унарного оператора", это может показаться немного чужеродным.

но посмотрите, как дополнительные пробелы группируются и отделяют различные части if заявление и выражение: У вас есть --pending, так что -- явно является собственным оператором и тесно связан с pending. (Он уменьшается pending и возвращает результат уменьшается.) Тогда у вас есть ! отделенный от этого, так что это, очевидно, отдельный оператор, отрицающий результат. Наконец, у вас есть if( и ) вокруг всего выражение, чтобы сделать его if заявление.

и да, я убрал пробел между if и (, потому что (принадлежит до if. Это ( не является частью какой-то (!-- синтаксис, как это кажется в оригинале,( если часть синтаксис заявление.

пробел здесь служит для общения смысл, вместо того, чтобы следовать некоторым механическое кодирование норматив.

Comments

    Ничего не найдено.