问题
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
- Isw
"true"? (checking for!= 0
in this case)!(w=0)
- Setw
to0
, take the opposite of the result so the&&
chain continuesi.removeClass(css).data('w',0).val('')
- Remove the class, set the data to0
clear the value.
!i.val() && (w=1) && i.addClass(css).data('w',1).val(text);
!i.val()
- Is the input empty?(w=1)
- Setw
to1
i.addClass(css).data('w',1).val(text);
- Add the class, set the data to1
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 if
s. It's advantages being:
- Uses marginally fewer characters than the exploded nested
if
s, decreasing the payload that's delivered to the browser. - 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