S16
S16

Reputation: 2995

An explanation of && shorthand in JavaScript

Using a watermark plugin for jQuery, I'm attempting to jslint and minimize the functions but I've come across syntax I have never seen before wherein there are expressions where there really ought to be an assignment or function call:

(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);

I'm specifically interested in the following lines:

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

and

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

Can someone explain this shorthand and rewrite these functions in such a way that I could compare them to better to understand the shorthand myself?

Thank you.

Upvotes: 1

Views: 5125

Answers (6)

Ateş Göral
Ateş Göral

Reputation: 140182

These can be rewritten as:

// 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);
    }
}

Using && like this is just a shorthand for using nested ifs. It's advantages being:

  1. Uses marginally fewer characters than the exploded nested ifs, decreasing the payload that's delivered to the browser.
  2. Can be faster to read for the trained eye.

Though, I must say that the above examples are an abuse of this shorthand because the conditionals used are fairly complex. I only resort to this shorthand when I need to check a chain of simple things like in the following example:

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

Upvotes: 1

Tarka
Tarka

Reputation: 4043

Using

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

for this explanation, it allows you to string multiple commands together while ensuring that each is true.

This could also be represented by:

if (w) {

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

It first makes sure w evaluates to true, and if it is, it checks if w=0 is not true (w != 0). If this is also true, then it goes on to the actual command.

This is common shorthand in a lot of languages that use lazy evaluation: If the next evaluation is put in with and (&&) then the following commands will not be executed if it returns false. This is useful in the sort of situations where you only want to perform an action on something if the previous statement returns true, like:

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

to make sure object isn't null before using it, otherwise you would be accessing a null pointer.

Upvotes: 0

Nick Craver
Nick Craver

Reputation: 630637

Let's break each of the statements you're asking about down to their components:

w && !(w=0) && i.removeClass(css).data('w',0).val('');
  • w - Is w "true"? (checking for != 0 in this case)
  • !(w=0) - Set w to 0, take the opposite of the result so the && chain continues
  • i.removeClass(css).data('w',0).val('') - Remove the class, set the data to 0 clear the value.

!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
  • !i.val() - Is the input empty?
  • (w=1) - Set w to 1
  • i.addClass(css).data('w',1).val(text); - Add the class, set the data to 1 and set the text to whatever the watermark text is.

Both of these are just statements to really cut down on code, certainly at the expense of readability. If you're looking at a de-minified version this is very common, if you're not and this is the original, chase the author with a salad fork, the original should be more more readable than this IMO, though it's just fine for a minified version.

Upvotes: 3

Cristian Sanchez
Cristian Sanchez

Reputation: 32177

&& can be used as a "guard." Basically it means stop evaluating the expression if one of the operands returns a "falsy" value.

Negating an expression will convert it to a boolean value. Specifically one that is a negation of the expression depending on whether it's 'truthy' or 'falsy'.

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

Basically says:

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('')

Upvotes: 3

on_conversion
on_conversion

Reputation: 31

With respect to:

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

the code:

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

will only execute if

w

is truthy.

Upvotes: 0

g.d.d.c
g.d.d.c

Reputation: 48048

&& is And. It's for comparison / compound conditional statements. It requires that both conditions in an if statement be true. I do not think there is another way to rewrite it - that is the syntax for And.

Upvotes: 0

Related Questions