I have some text in an object's property. I'm testing to see if the object's property has text in it to display; if it doesn't then I display "-" instead of just a blank. It doesn't seem like there's a difference between:
if (MyObject.SomeText && MyObject.SomeText.length) { ... }
if (MyObject.SomeText && MyObject.SomeText.length > 0) { ... }
Are there any edge cases where one syntax would be preferable to the other?
Are there any edge cases where one syntax would be preferable to the other?
Only edge cases where MyObject.SomeText or MyObject.SomeText.length is not what you expect it to be – for instance:
MyObject = {
SomeText = {
length: -42
// or length: true
}
};
they give same result. Btw, if its "text", then if (MyObject.SomeText) is enough
No, they are equivalent, if the length equals to 0 then it is valued as false.
(This is possible because JS is not strongly typed, in strongly typed languages length would not be castable as boolean).
In javascript, a number is only considered "falsey" when it is 0. Any other value is "truthy". Therefore, the statements number != 0 (comparison, not identity) and !number are exactly equivalent.
The only way your two statements would differ is if length was something other than a positive number.
It's the same:
Boolean(MyObject.SomeText.length)
returns true if MyObject.SomeText.length != 0
returns false if MyObject.SomeText.length == 0
and
Boolean(MyObject.SomeText.length>0)
returns true if MyObject.SomeText.length > 0
returns false if MyObject.SomeText.length <= 0
But MyObject.SomeText.length can only be 0 or a positive integrer. So
If MyObject.SomeText.length == 0,
Boolean(MyObject.SomeText.length) returns false because MyObject.SomeText.length == 0
Boolean(MyObject.SomeText.length>0) returns false because MyObject.SomeText.length<=0
If MyObject.SomeText.length > 0,
Boolean(MyObject.SomeText.length) returns true because MyObject.SomeText.length != 0
Boolean(MyObject.SomeText.length>0) returns true because MyObject.SomeText.length > 0
Related
Why a = 0 || false returns false but not 0 in JavaScript?
Output from the debug console:
> a = 0 || false
false
> a
false
> a = 0
0
> a = a || false
false
> a
false
a = 0 || false
Let's decompose it, or let's follow javascript's logic.
assign some expression to a
the expression is being evaluated
|| tells us to pick first if it is truthy, otherwise pick second.
0 is NOT truthy, then pick the second option, which is obviously false
a=0 is an assigment.
However, when you do a=0 || false, your expression converts to 0 || false, the result of which is false.
a = a is no logical comparison but just an assign, so all you do is 0 = 0 || false and since 0 is considered false
Why not 0 then ?
because a condition always returns a boolean so 0 -> false
if you wanted to check if a equals a you'd have to write a == a
a = 0;
console.log(a, a = a || false, a == a || false );
This is because the last evaluated value for the operator || is the operand false. This is in keeping with short circuit evaluation for logical operator. If your expression were:
a = 0 || 22
The output would be 22and not a boolean (true OR false). Explanation: same as above. The last evaluated expression is operand 22 and that is returned.
Let me know if that answered your question.
Ref: https://codeburst.io/javascript-what-is-short-circuit-evaluation-ff22b2f5608c
Why does the expression 1 && 2 evaluate as 2?
console.log("1 && 2 = " + (1 && 2));
&& (and operator) returns the last (right-side) value as long as the chain is "truthy".
if you would try 0 && 2 -> the result would be 0 (which is "falsy")
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical_operators
According to MDN:
expr1 && expr2 returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
Because 1 can be evaluated to true, 1 && 2 returns 2.
According to this page:
Why 1 && 2 == 2
AND returns the first falsy value or the last value if none were found.
OR returns the first truthy one.
For multiple operators in same statement:
precedence of the AND && operator is higher than OR ||, so it executes before OR.
alert( 5 || 1 && 0 ); // 5
Because its and, all the values need to be evaluated only up to the first 0, and the value of the last evaluation is returned, and it's the last one.
Although not directly relevant here, note that there's a difference between bitwise and logical operators. The former tests bits that are the same and only return those, the latter reduces to only true (!=0) or false (=0), so contrary to intuition, bitwise AND and AND are not interchangable unless the values are exactly 0 or 1.
in JavaScript, 0 && 1 evaluates to 0, which is the lower of the two. Why, then, does 0.1 && 1 evaluate to 1, which is the higher of the two?
Similarly, why does 0 || 1 evaluate to 1, but 0.1 || 1 evaluate to 0.1
It has nothing to do with which value is larger, the operators will return the appropriate value for the spec.
In the case of && if the first parameter is false, it will be returned. Otherwise the second is returned. In your example 0.1 && 1, 0.1 is a truth-y value so 1 is returned. You could just as easily try 100000000 && 0.1 and see that 0.1 is returned. The reason that 0 && 1 returns 0 is because 0 is false-y so, per the spec, the first value gets returned.
Likewise, with || if the first parameter is true, it will be returned. Otherwise the second is returned.
You should check this out https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators.
Basically the && will take the first of the two if it is falsey otherwise it will take the second.
The opposite is true for ||.
The && and || operators do not return values based on inequalities such as < or >.
a && b works as:
if (a) {
return b;
}
else {
return a;
}
a || b works as:
if (a) {
return a;
}
else {
return b;
}
The if statements are based on the concept of "truthy" and "falsey" values, where 0, NaN, null, undefined, '', and false are all "falsey". All other values are "truthy".
0 && 1 evaluates to 0 because 0 is falsey.
0.1 && 1 evaluates to 1 because 0.1 is truthy.
There are several different things going on:
0 is bitwise false, and any number other than 0 evaluates to true, so the expression 0 && 1 evaluates to false && true, which is of course false.
1 is bitwise true, and as per above any number <> 0 also evaluates to true, so 0.1 && 1 evaluates to true && true, which is true.
Using the information above:
0 || 1 evaluates to false || true, which is true
The final example is perhaps the most interesting one, and it has to do with operator short-circuiting.
The logical or operator (||) short-circuits, or stops evaluating, as soon as it encounters a value that evaluates to true. Thus, if you are using logical or in an assignment operation, it will return the first true value in the expression.
Thus, 0.1 || 1 returns 0.1. But, if you were to evaluate 1 || 0.1, it would instead return 1.
As a related aside, the logical and operator (&&) will short-circuit as soon as it encounters a value that evaluates to false.
You're specifically discussing logical operators, which actually do not care about the numbers themselves. Your code could be rewritten as
0 && 1 - false && true
0.1 && 1 - true && true
0 || 1 - false || true
0.1 || 1 - true || true
I assume you're setting this to a variable like x or something. When you set it, the variable is being assigned as the first portion of the test that "fully" passes.
So, your cases above work like this:
The result is 0 because the test fails at 0 (0 && anything will fail).
The result is 1 because the test "fully" passes after checking the right-hand side of the equation. It checks that 0.1 is "truthy" and then checks that 1 is "truthy" and returns 1 since that was the last piece checked.
The result is 1 because the boolean logic checks 0 first, and then says "or 1". The "or 1" piece passes, so it returns 1.
The result is 0.1 because that is "truthy" and it doesn't need to check the second side of the equation.
Since this has nothing to do with the size of the numbers, just whether or not they are 0 or not 0, you can actually show this more clearly with using something like the following:
0 && -1 - false && true
0.1 && -2 - true && true
0 || -3 - false || true
0.1 || -4 - true || true
Consider empty JavaScript array:
var a = [];
alert(a == false); // shows true
alert(!a); // shows false!
How to explain this?
What are the rules?
From http://forums.whirlpool.net.au/archive/966449:
a == false:
In this case, the type of the left-hand side is object, the type of the right-hand side is boolean. Javascript first converts the boolean to a number, yielding 0. Then it converts the object to a "primitive", yielding the empty string. Next it compares the empty string to 0. The empty string is converted to a number, yielding 0, which is numerically equal to the 0 on the right-hand side, so the result of the entire expression is true.
See §11.9.3 of the ECMAScript spec for all the gory details.
(!a):
In this case Javascript converts the object to the boolean true, then inverts it, resulting in false.
The ! operator checks whether its operand is "falsy".
The following are true:
!false
!0
!null
!NaN
!undefined
!""
The == operator checks for loose equality, which has nothing to do with falsiness.
Specifically, a == b will convert to operands to numbers, then compare the numbers.
Strings containing numbers convert to the numbers that they contain; booleans convert to 0 and 1.
Objects are converted by calling valueOf, if defined.
Thus, all of the following are true:
"1" == 1
"0" == false
"1" == true
"2" != true
"2" != false
({ valueOf:function() { return 2; } }) == 2
({ valueOf:function() { return 1; } }) == true
The == operator when one of the operands if Boolean, type-converts the other to Number.
[] == 0;
Is equivalent to:
0 == 0;
You can see the complete details of The Abstract Equality Comparison Algorithm on the specification.
As you can see, an empty array object, when converted to Number, produces 0:
+[]; // 0
Number(0);
This is really because its toString method produces an empty string, for example:
[].toString(); // ""
+""; // 0
Number(""); // 0
When comparing an object to a primitive value via the == operator, the object coerces into an primitive value itself (number or string). In this case [] coerces into 0, then false coerces into 0:
[] == false
0 == false
0 == 0
which is true.
The ! operator coerces into boolean and then inverts the value. [] into boolean is true (like with any object). Then invert to become false
![]
!true
false
Not sure if this answers the question, but there is a new library for getting around all of Javascript's Typecasting weirdnesses:
Typecast.js
In a sentence, Typecast solves all the simple problems, so you can focus on the big ones. Typecast fixes what's wrong with Javascript by creating a complete platform for strongly-typed variables in Javascript.
Code-snippet 1:
if ( !x ) { /* do stuff */ }
Code-snippet 2:
if ( x == 0 ) { /* do stuff */ }
For what values of x do these two code-snippets differ?
I am asking because, although I read the chapter on == in the spec, I still find it hard to deal with situations like the above (where it is combined with ToBoolean coercion).
btw, I want to know this just for the sake of knowing it (I want to understand the language), so don't bother telling me about === or asking me what x is.
Update: I corrected the fist snippet. I meant !x.
[] == 0 is true; ![] is false
null == 0 is false; !null is true
NaN == 0 is false; !NaN is true
undefined == 0 is false; !undefined is true
!x will check whether x is "falsy".
x == 0 will check whether x is "equivalent to" 0.
Both of these terms are defined by the Javascript spec.
The following will give you true for the first and false for the second snippet:
NaN
null
undefined
And these will give you false for the first and true for the second snippet:
[]
"0" and any other string that converts to 0 using Number(x) such as "00", "000", "+0", and "-0" (which I will now call "noughty strings")
an array containing a single element that is 0, null, undefined or an empty or noughty string.
For everything else you'll get the same result for both snippets, although there may be one or two more cases I haven't thought of.
Here's an interesting one with regard to a non-empty String that has only space characters:
!!" "; // true
" " == true; // false
This is because when you do a == comparison, and one of the values being compared is a number or a boolean, an attempt is made to convert the other value to a number.
The reason you get the different result is that a string with only space characters converts to the number 0 (or falsey), while a string with only spaces converted to boolean via !! is seen as a non-empty string, and therefore true.
So:
var x = " ";
alert( !x ); // false
alert( x == 0 ); // true
EDIT:
Probably the key thing to remember is that when comparing a number or boolean to a non number type, == uses toNumber conversion if possible, while ! uses toBoolean conversion. They're not always the same.
It is easy to see the result of the toBoolean conversion using !!. As in:
alert( !![] ); // true
But you can't really see the result of the toNumber conversion when using ==.
You can, however, use the unary + to see the result of a toNumber conversion. As in:
alert( +[] ); // 0
I'm pretty sure that what happens in the case of an Array, is that it first gets a toString call. Therefore:
// ---------------------toString result-------toNumber result (from string)
alert( +[] ); // "" 0
alert( +[""] ); // "" 0
alert( +[" "] ); // " " 0
alert( +[0] ); // "0" 0
alert( +["0"] ); // "0" 0
alert( +["3"] ); // "3" 3
alert( +[3,4] ); // "3,4" NaN
Short answer: the two are almost always the same but not 100% the same.
An example would be (!'0') which is false whereas ('0' == 0) is true
Details:
From: http://www.joeyjavas.com/2007/08/04/javascript-true-false-checking-for-boolean-values/
Checking if a value is true or false is simple in JavaScript. All values evaluate to true, except for:
0
-0
null
undefined
NaN
empty string
false
Therefore, (!x) will be true for all of the above values of x and only those.
As for (x == 0), it will be true for any value of x which - when converted according to "==" conversion rules - is converted to 0 when compared to a number (for example, Boolean false value). Other examples that compare true to ==0 are objects which generate 0 from their valueOf() methods, or a string '0', or an empty Array ([])
The first test will succeed when x is non-zero, or evaluates to an object (as opposed to null or undefined), or is a non-empty string. So if x is 0 then the condition fails, but if it is "0" then it succeeds.
The second test will succeed when x is convertible to 0. This means it must not be null, undefined, or an object to pass this test. And it may be "0" or "".
In other words, these conditionals are not opposites. The value "0" will pass both tests, for example.
Code Snippet 1 will execute if x is "falsy" value. In Javascript, this means 0, -0, null, undefined, NaN, "", or false. Code Snippet 2, however, will only execute if x is zero. Unlike the first condition, this does not include other "falsy" values.
The difference between the two is that
if ( x ) { ... }
Tests whether x is "truthy"
Whereas
if ( x == 0 ) { ... }
Does type coercion between x and 0.
I presume you mean something like
if (x == 0) vs if (!x)
The main difference is type coercion of x to a number vs checking if x is falsy.
Clearly NaN itself will never equal 0 since its not a number. undefined will also coerce to NaN so that is not caught by == 0 I can't give a good explanation why null is not caught by 0 since Number(null) == 0
After some lookups, have to change my awnser.
There's no simple logic, implicit equality operations follows an algorithm.
http://interglacial.com/javascript_spec/a-11.html#a-11.9.3
I can't sum it up better then what the algoritm describes, it would just get more confusing.
So it's (!x) is equivalent to (typeof x === false) aka (not true)
And (x == 0) gets compared by algorithm.