In a browser console, entering 1===1 evaluates to true. Entering 1===1===1 evaluates to false.
I assume that this is because of the way the statement is evaluated:
1 === 1 === 1
becomes
(1 === 1) === 1
which evaluates to
true === 1
which is false.
Is this correct? If not, what's the real reason for this behaviour?
Yes, you're exactly right. Here you have two equality checks, which have the same operator precedence. First one evaluates first, then its result applies to the next equality check.
1===1===1is the same as (1===1)===1 which is true===1 which is false, because here you check by values AND their types. 1==1==1 will result in true, because it checks equality by values only, so 1==1==1 equal to (1==1)==1 equal to true==1 equal to true.
The === operator doesn't just test equality, but also type equality. Since an integer is not a boolean, true === 1 is false.
Compare:
true == 1; // true
true === 1; // false
Example.
Correct behaviour. Since
1===1 // value is true
but
true===1 // it's false
There are two reasons for this:
true is a boolean type where 1 is integer
simply, 1 is not equal to true.
so
1===1===1 // false
The behaviour that you mentioned is correct.
Its because === implies matching based on type and value.
true === 1 does not match on type, but true == 1 matches based on value.
if 1==1==1 then it will be true
Related
Having issues correctly triggering code in an if and or statement. I want the code in the statement to run when the defholdid var is equal to "cb_SR" AND if ANY of these variables are true: altRighttargets, inRightTargets, safetyRightTargets. I have checked each variable on their own and they all receive the values I expect. Here's the statement:
if (defholdid === "cb_SR" && (altRightTargets === true || inRightTargets === true || safetyRightTargets === true)) {
//code I want to trigger
};
I checked the statement with each individual expression, and I can get the code to trigger, so I think I'm incorrectly writing the statement.
Thanks,
Make sure that the variables you're comparing with true actually hold boolean values, not strings "true" or "false". If they contain these strings, the comparison with true will always be false. In the context of your OR grouping, that variable is effectively ignored.
The strict equality operator === will always be false for values of different types. But even if you change to the loose equality operator ==, true == "true" will be false. When comparing a boolean with another type, the boolean is converted to 0 or 1 first, and then this is compared with the other value (with additional type juggling possible). So true == "1" is true because 1 == "1", but true == "true" is false because 1 == "true" is false. As pointed out in this answer, we have the following cases of comparing a boolean with a string:
true == "true"; //false
true == "1"; //true
false == "false"; //false
false == ""; //true
false == "0"; //true
I have a variable which is either set to something or is undefined. I wish to pass to a function true if the variable is defined else false. Here is the function:
function f(areRowsSelectable){...}
Which of the following would you do?
f(v);
f(v?true:false);
Or something else?
I usually use double negation (which means applying the logical NOT operator twice) for explicit boolean conversion:
!!v
Examples:
!!'test' // true
!!'' // false
!!0 // false
!!1 // true
!!null // false
!!undefined // false
!!NaN // false
Alternatively, also Boolean(v) would work.
I would use the "typeOf" guard method.
It does not accept "truthy" arguments, so it depends on your function whether you can use it.
The tests are basically the same as czosel's answer, but his answer returns "truthy" while mine only accepts boolean true as true.
var tests = [
//filled string
'test',
//empty string
'',
//Numeric empty
0,
//Numeric filled
1,
//Null
null,
//Completely undefined
,
//undefined
undefined,
//Not-A-Number numeric value
NaN,
//Boolean true
true
];
for (var t = 0; t < tests.length; t++) {
var test = tests[t];
var results = {
test: test,
isTruthy: !!test,
isBoolTrue: (typeof test != "boolean" ? false : test),
isDefined: (test !== void 0)
};
console.log(results);
}
EDIT 1
Since the question could be interpreted in several ways, i have included a couple of more tests.
isTruthy matches czosel's answer. Registers truthy values like 1 as true.
isBoolTrue was my first interpretation where it checks strictly whether a value is boolean true.
isDefined simply returns if the variable contains anything at all.
if([]==true) //evalutes as false
//when i check empty array with true, if evaluating [] as false so it
if condition return false
if([]) //evalutes as true
//when i check empty array alone, if evaluating [] as true so it if
condition return true
why it is evaluating like that?
thanks
Based on abstract equality comparison algorithm your first code will be evaluated like below,
step 1 : ToNumber([]) == true
step 2 : ToPrimitive([]) == true
(ToNumber() will call ToPrimitve() when the passed argument is an object)
step 3 : "" == true
step 4 : 0 == true
step 5 : false == true
step 6 : false
And in your second case, [] is a truthy value, so if([]) will be evaluated to true always, here [] will not be converted as a primitive. Abstract equality comparison algorithm comes into play when you use == operator.
Another better example would be,
var x = [] || "hello";
console.log(x); // []
Since [] is a truthy value, x would be set with [] not "hello"
When you use only a variable as the condition (without comparison operators), Javascript will cast it to Boolean using the Boolean() function:
http://www.w3schools.com/js/js_booleans.asp
In your case, Boolean([]) = true so it returned as true.
Are there any cases where
x == y //false
x === y //true
is that ever possible in JS? :)
No. That's never possible. === checks for type and equality. == just checks for equality. If something isn't == it can never be ===.
It'd be impossible. == compares value, while === compares value and type. Your case would require an impossible condition.
a === b -> (typeof(a) == typeof(b)) && (value(a) == value(b))
a == b -> (value(a) == value(b))
You couldn't have the value comparisons in the == case be true while requiring the exact same comparison in === become false.
== - Returns true if the operands are equal.
=== - Returns true if the operands are equal and of the same type.
So, I'll say not possible.
Briefly, if === is true, then == will return true. If === returns false, then == may or may not return false.
Examples:
5===5 is true, which means that 5==5 also must be true.
'5'===5 is false, and '5'==5 is true.
'6'===5 is false, and '6'==5 is also false.
This behavior is because a===b checks to make sure that the value and type of a and b are equal, while a==b only checks to make sure that their values are equal.
I've just answered this question but I don't understand why it works the way it does.
Basically the problem can be simplified to this:
var b = new Boolean(false);
console.info(b == false); // Prints "true" - OK
console.info(b && true); // Prints "true" - but should be "false"
I assume there's some unintuitive automatic casting going on but I don't understand it would sometime be automatically casted to true, sometime to false. Any idea?
I guess this illustrates the problem better:
> false && 123
false // OK
> new Boolean(false) && 123
123 // ???
== does a lot of coercion:
Object == false =>
Object == 0 =>
Object.valueOf() == 0 =>
false == 0 =>
0 == 0 =>
true
Or if you follow the steps in the algorithm, it is
Step 7, Step 9, Step 6, Step 1 c iii.
The logical and just goes directly for ToBoolean, which always returns true for objects.
Note that new Boolean returns an object and not a boolean value.
Maybe the object b is true when doing (b && false) but doing to logical operation of true and false results to false.
If you do this:
var b = new Boolean(false);
console.info(b == false); // Prints "true" - OK
console.info(b && true); // Prints "true"
So even though the object b was set to false in the (b && true) it results to true because it exists and it's not set to null.
False AND False is false. Truth tables - AND only returns true if both arguments are true, and neither is in this case.
EDIT: True AND False is also false, so anything && False is false.
I'm not sure if I understand your question correctly but it look like the major issue derives from the fact that if (new Boolean(false)) evaluates to true. If you put expressions in an if statement or link them with logical operators (i.e. &&), JavaScript only checks if they are truthy or falsy. When it comes to boolean primitives, it is easy:
true -> truthy
false -> falsy
But when it comes to boolean objects, it looks different:
new Boolean(false) -> truthy
new Boolean(true) -> truthy
The reason for this is, that in JavaScript, every object (if not null) is truthy.