Объяснение сокращения && в JavaScript

Используя плагин водяных знаков для jQuery, я пытаюсь jslint и минимизировать функции, но я столкнулся с синтаксисом, который я никогда раньше не видел, где есть выражения, где действительно должен быть вызов присваивания или функции:

(function($) {

    $.fn.watermark = function(css, text) {

        return this.each(function() {

            var i = $(this), w;

            i.focus(function() {
                w && !(w=0) && i.removeClass(css).data('w',0).val('');
            })
                .blur(function() {
                    !i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
                })
                .closest('form').submit(function() {
                    w && i.val('');
                });

            i.blur();
        });
    };

    $.fn.removeWatermark = function() {

        return this.each(function() {

            $(this).data('w') && $(this).val('');
        });
    };
})(jQuery);

Меня особенно интересуют следующие строки:

w && !(w=0) && i.removeClass(css).data('w',0).val('');

а также

!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);

Может ли кто-нибудь объяснить эту стенографию и переписать эти функции таким образом, чтобы я мог сравнить их, чтобы лучше понять стенографию сам?

Спасибо.

6 ответов

Решение

Давайте разберем каждое из утверждений, о которых вы просите, до их компонентов:

w && !(w=0) && i.removeClass(css).data('w',0).val('');
  • w - Является w "правда"? (проверка на != 0 в этом случае)
  • !(w=0) - Задавать w в 0принять противоположный результат, чтобы && цепочка продолжается
  • i.removeClass(css).data('w',0).val('') - Удалить класс, установить данные в 0 очистить значение.

!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
  • !i.val() - Вход пуст?
  • (w=1) - Задавать w в 1
  • i.addClass(css).data('w',1).val(text); - Добавить класс, установить данные в 1 и установите текст в соответствии с текстом водяного знака.

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

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

Отрицание выражения преобразует его в логическое значение. Конкретно тот, который является отрицанием выражения в зависимости от того, является ли это "правдивым" или "ложным".

w && !(w=0) && i.removeClass(css).data('w',0).val('');

В основном говорит:

w is "truthy" (defined, true, a string, etc.)
AND set w to zero + convert the expression to true (because (w=0) would evaluate to 0, which is falsy)
AND evaluate i.removeClass(css).data('w',0).val('')

Они могут быть переписаны как:

// w && !(w=0) && i.removeClass(css).data('w',0).val('');
if (w) {
    if (!(w=0)) {
        i.removeClass(css).data('w',0).val('');
    }
}

//!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
if (!i.val()) {
    if (w=1) {
        i.addClass(css).data('w',1).val(text);
    }
}

С помощью && как это просто сокращение для использования вложенных ifs. Это преимущества:

  1. Использует немного меньше символов, чем вложенный ifs, уменьшая полезную нагрузку, которая доставляется в браузер.
  2. Можно быстрее читать для тренированного глаза.

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

function log(s) {
    window.console && console.log && console.log(s);
}

&& - это А. Это для сравнения / составных условных выражений. Это требует, чтобы оба условия в операторе if были истинными. Я не думаю, что есть другой способ переписать его - это синтаксис для А.

Что касается:

w && !(w=0) && i.removeClass(css).data('w',0).val('');

код:

!(w=0) && i.removeClass(css).data('w',0).val('');

будет выполняться только если

w

это правда

С помощью

w && !(w=0) && i.removeClass(css).data('w',0).val('');

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

Это также может быть представлено:

if (w) {

    w = 0;
    i.removeClass(css).data('w',0).val('');
}

Сначала убедитесь, что w оценивается как истина, и если это так, он проверяет, если w=0 неправда (w != 0). Если это также верно, то это переходит к фактической команде.

Это обычное сокращение во многих языках, которые используют ленивую оценку: если следующая оценка ставится с and (&&) тогда следующие команды не будут выполнены, если он вернет false. Это полезно в ситуациях, когда вы хотите выполнить какое-либо действие, только если предыдущий оператор возвращает true, например:

if (object != null && object.property == true)

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

Другие вопросы по тегам