Is 0 considered true in ES6? Or all strings considered true?
this is returning true:
var value = "0";
var isTrue = value ? true : false; // true
I thought === was for strict equality.
If it has changed is there a way to get the old way for compatibility sake?
UPDATE:
Thanks. The value I'm receiving will always be a string so I'll check for "0" and "false":
var booleanValue = value && value!=="0" && value!=="false" ? true : false;
"0" is true because it's just a string and has a value, but the 0 as a number is considered false
This is a list of all falsy values in javascript:
false
0
'' or ""
null
undefined
NaN
Only the String '' is a falsy value, meaning that it is an empty string.
'0' is a string with content so it isn't a falsy value, but 0 is one.
All strings that have characters in them are truthy.¹ Only the empty string, "", is falsy.¹
0 (the number) is falsy. "0" is not.
I thought === was for strict equality.
It is. There is no === check in your code. The conditional operator (? :) doesn't do an === check on the condition operand. It does a boolean check, just like if does.
If you used ===, it you'd get false:
var isTrue = value === true ? true : false; // false
Of course, in that case, there's no point to the conditional operator:
var isTrue = value === true; // false
The value I'm receiving will always be a string so I'll check for "0" and "false":
var booleanValue = value && value!=="0" && value!=="false" ? true : false;
It depends on what you want to do and what possible values you might get. For instance, if what you're getting will be a string containing a valid number or a valid boolean (as seems the case from your example there), you could use JSON.parse to parse it to a number or boolean:
var isTrue = !!JSON.parse(str);
(The !! is so that 0 and NaN convert to false and a number that isn't 0 or NaN converts to true.) But again, it depends on what you're receiving, a switch with the values you're expecting may be better, etc.
¹ "falsy" and "truthy":
"falsy" - coerces to false when used as a boolean, such as in a conditional operator as in your question. The falsy values are 0, NaN, null, undefined, "", and of course, false.
"truthy" - coerces to true when used as a boolean. All non-falsy values are truthy, including "0" and "false".
You're inspecting a string containing 0 instead of an actual number 0.
"0" // string
0 // number
A string is considered false if it is equal to '', all other strings are considered true
A number is considered false if it is either 0 or NaN, all other numbers are considered true.
=== indeed means strict equal, meaning a comparison is made on both type and value. So:
true == 1 // true
true === 1 // false
Actually its other way around, for any string, it will return True, for 0 as an integer, it will return False, and for 1 as an integer, it will return True
var value0 = 0;
var value1 = 1;
var str = "23123";
var isTrue0 = value0 ? true : false;
var isTrue1 = value1 ? true : false;
var isTrueStr = str ? true : false;
console.log('0: ' + isTrue0);
console.log('1: ' + isTrue1);
console.log('string: ' + isTrueStr);
isTrue = value - classic error using assignment rather than comparison.
Related
I have two statements like this. Why do they both evaluate to false?
console.log([] == true)
console.log(![] == true)
If [] == true is false shouldn't ![] == true result to true?
It's the way coercion works.
The first step of coercion is to convert any non primitive types to primitive types, then using a set of rules convert the left, right or both sides to the same type. You can find these rules here.
In your case [] == true, would pass through these 4 steps:
[] == true
[] == 1
"" == 1
0 == 1
Whereas based on operator precedence the ! in ![] == true is executed first so the expression is converted to false == true which is obviously false.
You can try the live demo by Felix Kling to better understand how the sameness operator works.
In more words:
The value ![] is false, because [] is an Object (arrays are objects) and all objects, not including null, are truthy. So any array, even if it is empty will always be a truthy, and the opposite of a truthy is always false. The easiest way to check if a value is a truthy is by using !!.
console.log("![]: " + ![]);
console.log("!![]: " + !![]);
When you are using a loose comparison (using == instead of ===) you are asking the JavaScript engine to first convert the values into the same type and then compare them. So what happens is the values get converted according to a set of rules, once they are the same type, they get compared though the same process as a strict equality check (===). The first change that [] goes through is to get converted to a string, the string version of an empty array is an empty string "", the empty string is then converted to a number, the numeric value of an empty string is 0, since the numeric value of true is 1 and 0 != 1, the final output is false.
console.log("[] == true => `" + ([] == true) + "`");
console.log("String([]) => `" + String([]) + "`");
console.log("Number('') => `" + Number("") + "`");
console.log("Number(true) => `" + Number(true) + "`");
As per the Abstract Equality Comparison Algorithm - http://es5.github.io/#x11.9.3
Types of x and y are checked when x == y is to be checked.
If no rule matches, a false is returned.
For [] == true , rule 7 matches, so a result of [] == ToNumber(true) is returned i.e. false is returned.
Reason you're getting the same result for ![] == true, because ![] returns false, and false == true returns false .
To get opposite result for your second operation, add a precedence (i.e. wrap) to your expression with braces.
console.log(!([] == true)); // returns true
Put ![] in the console. It's false.
So ![] == true is the same as false == true, which is false.
[] != true is true though
None of the answers so far has addressed the main problem. [Edit: This is no longer true. See Nick Zoum's answer.]
The question essentially is this:
[] == true returns false
=> [] is not true
=> [] is false (because something not true must be false)
=> ![] should be true, since negation of false is true. Then why does ![] == true return false?
[] is actually truthy. (So ![] is actually falsy.)
Still, [] == true returns false -- the reason is coercion. It's another of Javascript's gotchas.
When an array is checked for equality explicitly against a boolean value (that is, against true or false), its elements are first converted to strings and then joined together. An empty array therefore becomes "" — therein lies the problem, because an empty string is falsy.
In brief, an empty array is truthy, but it's coerced (when being compared to a boolean value) to an empty string, which is falsy.
Note the following, which comes from https://www.nfriedly.com/techblog/2009/07/advanced-javascript-operators-and-truthy-falsy/
Arrays are particularly weird. If you just test it for truthyness, an
empty array is truthy. HOWEVER, if you compare an empty array to a
boolean, it becomes falsy:
if ( [] == false ) {
// this code runs }
if ( [] ) {
// this code also runs }
if ([] == true) {
// this code doesn't run }
if ( ![] ) {
// this code also doesn't run }
(This is because when you do a comparison, its elements are turned to Strings and joined. Since it's empty, it becomes "" which is then falsy. Yea, it's weird.)
Read https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/
Rule in JavaScript for The Equals Operator (==)
if
type(x) type(y) result
1.x and y are the same type See Strict Equality (===) Algorithm
2.null Undefined true
3.Undefined null true
4. Number String x == toNumber(y)
5. String Number toNumber(x) == y
6. Boolean (any) toNumber(x) == y
7. (any) Boolean x == toNumber(y)
8.String or Number Object x == toPrimitive(y)
9.Object String or Number toPrimitive(x) == y
***10.otherwise… false
I have two statements like this. Why do they both evaluate to false?
console.log([] == true)
console.log(![] == true)
If [] == true is false shouldn't ![] == true result to true?
It's the way coercion works.
The first step of coercion is to convert any non primitive types to primitive types, then using a set of rules convert the left, right or both sides to the same type. You can find these rules here.
In your case [] == true, would pass through these 4 steps:
[] == true
[] == 1
"" == 1
0 == 1
Whereas based on operator precedence the ! in ![] == true is executed first so the expression is converted to false == true which is obviously false.
You can try the live demo by Felix Kling to better understand how the sameness operator works.
In more words:
The value ![] is false, because [] is an Object (arrays are objects) and all objects, not including null, are truthy. So any array, even if it is empty will always be a truthy, and the opposite of a truthy is always false. The easiest way to check if a value is a truthy is by using !!.
console.log("![]: " + ![]);
console.log("!![]: " + !![]);
When you are using a loose comparison (using == instead of ===) you are asking the JavaScript engine to first convert the values into the same type and then compare them. So what happens is the values get converted according to a set of rules, once they are the same type, they get compared though the same process as a strict equality check (===). The first change that [] goes through is to get converted to a string, the string version of an empty array is an empty string "", the empty string is then converted to a number, the numeric value of an empty string is 0, since the numeric value of true is 1 and 0 != 1, the final output is false.
console.log("[] == true => `" + ([] == true) + "`");
console.log("String([]) => `" + String([]) + "`");
console.log("Number('') => `" + Number("") + "`");
console.log("Number(true) => `" + Number(true) + "`");
As per the Abstract Equality Comparison Algorithm - http://es5.github.io/#x11.9.3
Types of x and y are checked when x == y is to be checked.
If no rule matches, a false is returned.
For [] == true , rule 7 matches, so a result of [] == ToNumber(true) is returned i.e. false is returned.
Reason you're getting the same result for ![] == true, because ![] returns false, and false == true returns false .
To get opposite result for your second operation, add a precedence (i.e. wrap) to your expression with braces.
console.log(!([] == true)); // returns true
Put ![] in the console. It's false.
So ![] == true is the same as false == true, which is false.
[] != true is true though
None of the answers so far has addressed the main problem. [Edit: This is no longer true. See Nick Zoum's answer.]
The question essentially is this:
[] == true returns false
=> [] is not true
=> [] is false (because something not true must be false)
=> ![] should be true, since negation of false is true. Then why does ![] == true return false?
[] is actually truthy. (So ![] is actually falsy.)
Still, [] == true returns false -- the reason is coercion. It's another of Javascript's gotchas.
When an array is checked for equality explicitly against a boolean value (that is, against true or false), its elements are first converted to strings and then joined together. An empty array therefore becomes "" — therein lies the problem, because an empty string is falsy.
In brief, an empty array is truthy, but it's coerced (when being compared to a boolean value) to an empty string, which is falsy.
Note the following, which comes from https://www.nfriedly.com/techblog/2009/07/advanced-javascript-operators-and-truthy-falsy/
Arrays are particularly weird. If you just test it for truthyness, an
empty array is truthy. HOWEVER, if you compare an empty array to a
boolean, it becomes falsy:
if ( [] == false ) {
// this code runs }
if ( [] ) {
// this code also runs }
if ([] == true) {
// this code doesn't run }
if ( ![] ) {
// this code also doesn't run }
(This is because when you do a comparison, its elements are turned to Strings and joined. Since it's empty, it becomes "" which is then falsy. Yea, it's weird.)
Read https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/
Rule in JavaScript for The Equals Operator (==)
if
type(x) type(y) result
1.x and y are the same type See Strict Equality (===) Algorithm
2.null Undefined true
3.Undefined null true
4. Number String x == toNumber(y)
5. String Number toNumber(x) == y
6. Boolean (any) toNumber(x) == y
7. (any) Boolean x == toNumber(y)
8.String or Number Object x == toPrimitive(y)
9.Object String or Number toPrimitive(x) == y
***10.otherwise… false
There is two kind of JavaScript code for investigating empty/full variable:
if(variable == ''){}
if(!variable){}
I tested both of them, and I achieved identical result. Now I want to know, (first) are they equivalent? And (second) which one is more standard for checking empty/full variable?
var variable1 = 'string';
var variable2 = 12;
var variable3 = true;
if(variable1 == ''){alert('empty-one');}
if(variable2 == ''){alert('empty-one');}
if(variable3 == ''){alert('empty-one');}
if(!variable1){alert('empty-two');}
if(!variable2){alert('empty-two');}
if(!variable3){alert('empty-two');}
As you see, there is no alert.
First is not standard, it only works for defined empty string.
Other will work if value is not truthy ( means something meaningful)
e.g var a;
a == '' will give false result
! a will produce true
e.g. var a = null;
a == '', // false
! a // true
var a = false;
a == '' // fase
! a // true
var a = NaN
a == '' // false
! NaN // true
true == 'true' // false, Boolean true is first converted to number and then compared
0 == '' // true, string is first converted to integer and then compared
== uses The Abstract Equality Comparison Algorithm to compare two operands
For more detail visit http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3
In javascript null,'',0,NaN,undefined consider falsey in javascript.
In one sense you can check empty both way
But your first code are checking is it ''
and your 2nd condition is checking is your value are one of them (null,'',0,NaN,undefined)
In my view your 2nd condition is better then first as i don't have to check null,'',0,NaN,undefined seperately
No they are not equivalent. In case first it checks whether the value of variable is equal to the empty string('') or not. So case first will be true iff variable's value is ''. But second case will be true for all the values which are falsey i.e. false, 0, '', null, undefined.
Can someone explain me how this function works? I know the ternary operator, so I understand the part, that he checks if flag is true, and if not then use the 2. value. But I don't understand why flag is a Boolean in the first place and why it switches from true to false and vice versa when animate() is being called...
flag = $texte.data('animToggle');
$texte.data('animToggle', !flag);
$texte.animate({
'left': flag ? '-51%' : '0'
})
JavaScript has truthy and falsy values. These are values which equate to true and false when evaluated as Boolean. This means that true and false aren't the only values which can represent true or false data.
For example, if $texte.data('animToggle') is equal to 0 it will be falsy as 0 is a falsy value.
Example 1: 1000
1000 is a truthy value, so this will output "True":
var flag = 1000;
console.log(flag ? "True" : "False");
> "True"
Example 2: ""
"" (empty string) is a falsy value, so this will output "False":
var flag = "";
console.log(flag ? "True" : "False");
> "False"
The ! (Logical NOT) operator converts a value to Boolean and negates it. $texte.data('animToggle', !flag); sets the animToggle data property of $texte to the opposite of what it previously was.
!true // False
!1000 // False
!false // True
!"" // True
To the best of my knowledge, (x == false) should do the same thing as !x, as both of them try to interpret x as a boolean, and then negates it.
However, when I tried to test this out, I started getting some extremely strange behavior.
For example:
false == [] and false == ![] both return true.
Additionally
false == undefined and true == undefined both return false, as does
false == Infinity and true == Infinity and
false == NaN and true == NaN.
What exactly is going on here?
http://jsfiddle.net/AA6np/1/
It's all here: http://es5.github.com/#x11.9.3
For the case of false == []:
false is converted to a number (0), because that is always done with booleans.
[] is converted to a primitive by calling [].valueOf().toString(), and that is an empty string.
0 == "" is then evaluated by converting the empty string to a number, and because the result of that is also 0, false == [] is true.
For the case of false == ![]:
The logical not operator ! is performed by returning the opposite of ToBoolean(GetValue(expr))
ToBoolean() is always true for any object, so ![] evaluates to false (because !true = false), and therefore is false == ![] also true.
(false == undefined) === false and (true == undefined) === false is even simpler:
false and true are again converted to numbers (0 and 1, respectively).
Because undefined cannot be compared to a number, the chain bubbles through to the default result and that is false.
The other two cases are evaluated the same way: First Boolean to Number, and then compare this to the other number. Since neither 0 nor 1 equals Infinity or is Not A Number, those expressions also evaluate to false.
The abstract equality algorithm is described in section 9.3 of the specification.
For x == y where x = false and y = []:
Nope. Types are not equal.
Nope, x is not null.
Nope. x is not undefined.
Nope, x is not a number
Nope, x is not a string.
Yes, x is a boolean, so we compare ToNumber(x) and y.
Repeat the algorithm, x=0 and y=[].
We end at step 8:Type(x) == number. and Type(y) == object.
So, let the result be x == ToPrimitive(y).
ToPrimitive([]) == ""
Now, repeat the algorithm again with x=0 and y="". We end at 4: "return the result of the comparison x == ToNumber(y)."
ToNumber("") == 0
The last repetition of the algorithm ends at step 1 (types are equal). By 1.c.iii, 0 == 0, and true is returned.
The other results can be obtained in a similar manner, by using the algorithm.
false == []
Using == Javascript is allowed to apply conversions. The object will convert into a primitive to match type with the boolean, leaving an empty string. The false will convert into a number 0. The compares the empty string and the number 0. The string is converted to a number which will be 0, so the expression is "true"
![]
Javascript converts the object to the boolean true, therefore denying true ends being false.
false == undefined true == undefined
false == Infinity and true == Infinity
false == NaN and true == NaN
Again a bit of the same! false is converted to 0, true to 1. And then, undefined is converted to a number which is... NaN! So false in any case
I would recommend to use === !== as much as you can to get "expected" results unless you know very well what you are doing. Using something like Boolean(undefined) == false would also be nice.
Check ECMAScript specifications for all the details when converting stuff.