An explanation of && shorthand in JavaScript

限于喜欢 提交于 2020-01-03 05:24:07

问题


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.


回答1:


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.




回答2:


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



回答3:


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



回答4:


&& 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.




回答5:


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.




回答6:


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.



来源:https://stackoverflow.com/questions/3859433/an-explanation-of-shorthand-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!