In the code at our company i see the following.
if (someStuff != null) {
if (someStuff != "") {
doThatThing ();
}
}
While it's fully correct and valid, i'd like to rewrite it
as follows.
if (someStuff != null && someStuff != "")
doThatThing ();
It is very widely considered good style when writing javascript to
never omit the braces of a block statement from around the code
executed in - if/else - branches. It is extremely common to have a
single statement conditionally executed and then to realise that a
second statement will need to be added to that branch. With the braces
already in place all you do is add the statement, but without the
braces you often get fooled by the indentation into adding the
statement at the existing level of indentation and not seeing that
only one statement is going to conditionally executed and any that
follow it will be unconditionally executed. The usual result is a
confusing and hard to track down bug.
I know that some languages will evaluate the first
condition of the conjunction and, provided that it
fails, conclude that the statement is not to be
performed. I'd like to assume so in this case as
well, but wishing not to show arrogance and
know-better-ism, i'd like to check with more
experienced programmers first.
Will JS evaluate the whole konjunction or will it
be intelligent enough to stop as the first partial
condition fails? Is it depending on the platform
used?
The language specification requires short circuiting, and no
implementations have been observed to fail to correctly implement the
specification in this regard.
However, your simplification looks like it probably still falls short
of an optimum outcome. The first test, - someStuff != null -, will be
false for null and undefined values, so those two values are excluded
by the first test. The second test, - someStuff != "" -, will be false
for boolean false, numeric zero and empty strings. So the values that
can pass the combined test are all[*1] objects (including functions),
non-zero numbers (including NaN), non-empty strings, and boolean true.
[*1] Actually not all objects will pass the - someStuff != "" - test
because the comparison with a string implies type-conversion so an
object with a - toString - method that returned the empty string would
be equal to the empty string primitive. That is -
alert({toString:function(){return '';}} == ''); - alerts "true".
An alternative test could be:-
if(someStuff){
doThatThing ();
}
- where the value of - someStruff - is implicitly type-converted to
boolean and since the empty string, boolean false, numeric zero and
NaN, the undefined value and null all type-convert to boolean false
the only practical differences between that test and your previous one
is that the NaN numeric value will not pass the test (which is
probably a good idea) and that all objects would pass regardless of
how they type-convert to primitive values. While the type-converting
to boolean test is shorter simpler and faster than the original (which
includes at least one implicit type-conversion to boolean anyway).