0 === (0 || 6) // returns false
false === (false || 6) // returns false
(false === false || false === 6) // returns true
(0 === 0 || 0 === 6) // returns true
console.log( 0 === (0 || 6) );
console.log( false === (false || 6) );
console.log( (false === false || false === 6) );
console.log( (0 === 0 || 0 === 6) );
what gives? I ran across this scenario earlier and don't get it.
0 === (0 || 6) // returns false
It's all about order of operations. That returns false because the parenthesis are evaluated first. So (0 || 6) returns 6 and 0 === 6 is false
false === (false || 6) // returns false
(false === false || false === 6) // returns true
(0 === 0 || 0 === 6) // returns true
The rest are easy to follow after that explanation.
0 === (0 || 6) is equivalent to 0 === 6 which is of course false.
false === (false || 6) is equivalent to false === 6 which is also obviously false.
(false === false || false === 6) is equivalent to true || false which is of course true.
(0 === 0 || 0 === 6) is also equivalent to true || false.
Look up "operator precedence". That'll help you wrap your head around javascript in the future.
First, you should know the operators priority.
Second, you should know how the operators work and what they return.
Here is the documentation you can take it as reference.
console.log( 0 === (0 || 6) );
// (0 || 6) returns 6 because 0 is falsy,
// so it becomes 0 === 6. It is obviously return false.
console.log( false === (false || 6) );
(false || 6) is equals (0 || 6), so we get (false === 6) = false.
console.log( (false === false || false === 6) );
// this is three part. === is prior to ||,
// so we should do (false === false) and (false === 6).
// (false === false) is true and (false === 6) is false,
// so we get (true || false) = true
console.log( (0 === 0 || 0 === 6) );
// (0 === 0) is true and (0 === 6) is false,
// so true || false is true.
By the way, most of the JavaScript operator do type conversion
whether the two sides is not the type the operator want.
Here's something you can take a look:
https://javascript.info/type-conversions
From your question, I am guessing you are not familiar with how AND & OR are used or works.
So,
| stands for bitwise OR
and, & stands for bitwise AND
It is a common method of writing AND as && and OR as ||.
For AND, following are the scenarios:
1 && 1 => 1
1 && 0 => 0
0 && 1 => 0
0 && 0 => 0
For OR, following are the scenarios:
1 || 1 => 1
1 || 0 => 1
0 || 1 => 1
0 || 0 => 0
In the above, 1 can be any non-zero integer or value (but we denote it by one, meaning high).
So, if you write,
0 === ( 0 || 6 ),
then, ( 0 || 6 ) is already true, then, if you compare true with 0, then it is always going to be false.
Whereas, if you you change the above condition as:
0 == ( 0 && 6 ), (EDITTED)
( 0 && 6 ) becomes false, and then 0 == false becomes true.
=== and == are different because the second one just checks if they are equal or not, but it does not check if they are exactly same. === checks if the values are identical, meaning exactly same.
I hope my answer was helpful.
Related
I got stuck on this exercise. I don't understand why they need to have the first condition. Can I ignore that part?
The exercise is from https://www.w3resource.com/javascript-exercises/javascript-basic-exercise-46.php:
Write a JavaScript program to check two given non-negative integers that whether one of the number (not both) is multiple of 7 or 11.
function valCheck(a, b) {
if (!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
} else
return false;
}
console.log(valCheck(14, 21));
console.log(valCheck(14, 20));
console.log(valCheck(16, 20));
TL;DR – No, it's not redundant!
Write a JavaScript program to check whether exactly one of the two given non-negative integer numbers is a multiple of 7 or 11.
To explain why it's not redundant, let's break this solution function down.
function valCheck(a, b) {
if (!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
} else
return false;
}
First Conditional
The first condition is !((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0)). The x % n == 0 expressions are checking whether the given x is divisible by (a multiple of) either 7 or 11, but the expression is written in an overly verbose way that makes it a little difficult to understand.
Using De Morgan's law, we can rewrite it:
!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))
⇔
!(a % 7 == 0 || a % 11 == 0) || !(b % 7 == 0 || b % 11 == 0)
⇔
(a % 7 != 0 && a % 11 != 0) || (b % 7 != 0 && b % 11 != 0)
Now, we can tell that this condition is checking for the case where either a or b isn't divisible by 7 nor 11.
When this condition is true, we return the result of a second condition. If it is false, then we know neither input is a multiple of 7 or 11, so we return false outright.
Second Conditional
The second condition is:
(a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0)
This one is much less opaque than the first, and checks whether any of the 4 sub-conditions are true (the parenthesis are irrelevant here, since they're all "or" || operators).
Since we already know from the first condition that at least one of the inputs isn't a multiple of 7 or 11, we can now simply return whether at least of the inputs is. Put another way, if we know that this second condition is true, then we can be certain that exactly one of the numbers is a multiple of 7 or 11.
Are the Conditions Redundant?
So to answer your question, no, the first conditional isn't redundant, since it checks for whether at least one of the inputs isn't a multiple or 7 or 11. We need both of the conditional expressions to properly check that exactly one of the inputs is a proper multiple or 7 or 11.
If the "but not both" clause wasn't there, then we could use just the second conditional expression, but since it is, we need both pieces of information.
Wanted to note, I lied a little in saying we need both expressions, since it is indeed possible to solve this exercise with a single expression!
function valCheck(a, b) {
return (a % 7 == 0 || a % 11 == 0) != (b % 7 == 0 || b % 11 == 0);
}
console.log(valCheck(14, 21)); // false
console.log(valCheck(14, 20)); // true
console.log(valCheck(16, 20)); // false
I'll leave it to the reader to figure out why this works!
There are many repeating functions, let's refactor for clarity:
function isMultipleOf7Or11(num) {
return num % 7 == 0 || num % 11 == 0;
}
function valCheck(a, b) {
var isAVarMultiple = isMultipleOf7Or11(a);
var isBVarMultiple = isMultipleOf7Or11(b);
if(!(isAVarMultiple && isBVarMultiple) {
return isAVarMultiple || isBVarMultiple;
else
return false;
}
}
Now to simplify the condition:
!(isAVarMultiple && isBVarMultiple) is also equal to !isAVarMultiple || !isBVarMultiple according to De Morgan's negation of a conjuction, which returns true if at least one of them is not a multiple of 7 or 11
and in the return value the condition isAVarMultiple || isBVarMultiple returns true if at least one of them is a multiple of 7 or 11
We can conclude that it is a XOR operation on two values, which would return true only if one and only one of the variables is a multiple of 7 or 11
Outputs:
console.log(valCheck(14, 21));
returns false
console.log(valCheck(14, 20));
returns true
console.log(valCheck(16, 20));
returns false
I recommend you look at the code by the debugger, not for this example only, but when you will be stuck in difficult situations, you can split your code in a small and readable pieces and see what is happening in there.
For example this can be transformed to this
Not Sure If I can make this more readable :)
function valCheck (a, b) {
debugger;
const canADividedTo7 = a % 7 == 0;
const canADividedTo11 = a % 11 == 0;
const canADividedTo7Or11 = canADividedTo7 || canADividedTo11;
const canBDividedTo7 = b % 7 == 0;
const canBDividedTo11 = b % 11 == 0;
const canBDividedTo7Or11 = canBDividedTo7 || canBDividedTo11;
// true when both both side of expression are true
const canAAndBDividedTo7Or11 = canADividedTo7Or11 && canBDividedTo7Or11;
// true when at least one of the expression is true
const canAOrBDividedTo7Or11 = canADividedTo7Or11 || canBDividedTo7Or11;
//
if (!canAAndBDividedTo7Or11) {
return canAOrBDividedTo7Or11;
} else {
return false;
}
}
console.log(valCheck(14, 21));
console.log(valCheck(14, 20));
console.log(valCheck(16, 20));
Who would write anything that inane and complicated?
Let's take this mess:
function valCheck(a, b) {
if (!((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
} else
return false;
}
and refactor it into something readable:
function valChec( a, b ) {
const aIsDivisible = a % 7 === 0 || a % 11 === 0 ;
const bIsDivisible = b % 7 === 0 || b % 11 === 0 ;
return aIsDivisible ? !bIsDivisible : bIsDivisible;
}
You could even make it a one-liner with a ternary expression (at the expense of a few more division ops... but given the original code, that's not an issue):
const isMagic = x => x % 7 === 0 || x % 11 === 0;
const valCheck = (a,b) => isMagic(a) ? !isMagic(b) : isMagic(b);
Yes, you're right in finding the answer to that question redundant; also, I believe the ! is incorrect and makes the code always return false.
A more reasonable solution to the problem would be to just return the boolean expression:
function valCheck(a, b) {
return ((a % 7 == 0 || a % 11 == 0) || (b % 7 == 0 || b % 11 == 0));
}
Alternatively, if you really wanted to use an if/else construct, it would be better to just return true in the first case:
function valCheck(a, b) {
if ((a % 7 == 0 || a % 11 == 0) && (b % 7 == 0 || b % 11 == 0))
return true;
else
return false;
}
Hope this helps with your understanding of JavaScript! But as suggested in the comments, you might want to learn JavaScript from other sources.
can someone explain this comparison statement ?
I understand how to compare with && and || but the one liner below does something else
typeof(varName) === 'undefined' == 0
Lets say that varName is undefined. Your line of code goes through these steps (each new line is the next step):
typeof(varName) === 'undefined' == 0
typeof(undefined) === 'undefined' == 0
'undefined' === 'undefined' == 0
true == 0
false
Now lets say that varName is defined as equal to 5:
typeof(varName) === 'undefined' == 0
typeof(5) === 'undefined' == 0
'number' === 'undefined' == 0
false == 0
true
This is bad code. You can get the same result with typeof(varName) !== 'undefined'
typeof(varName) === 'undefined' == 0
The above expression can also be written as
!(typeof(varName) === 'undefined')
Instead of using Not operator (!) they have used == 0. But if you do ===0, it will not work because it will also check for datatype and will always return false.
example :
true == 0 => false
false == 0 => true
But if you use ===
true === 0 => false
false === 0 => false
Note: typeof(varName) === 'undefined' == 0 is a bad way to do it.
Use not operator:
!(typeof(varName) === 'undefined')
The question is quite simple:
Infinity == Infinity
>> true
Infinity == 1/0
>> true
Infinity == Infinity == 1/0
>> false
Why the last evaluation is false?
Because Infinity == Infinity == 1/0 is basically
(Infinity == Infinity) == 1/0
so
(true) == 1/0
is false.
its look trying like below..
var d = (2 == 2);
console.log(d) //true
console.log(d == 2); //[true == 2] false
comparison == return always boolean true or false[1 or 0]
I have this html:
<input type='number' id='length' step='0.1' min='0'; max='5'>Length
and this Javascript
num=document.getElementById('length').value;
if(num==1 || 2 || 3 || 4|| 5){
num='0'+num;
}
My problem is this: while I only want the code inside the brackets to execute if the number from the input is an integer, it also activates if it detects 0.8 or some other decimal. Any Idea why? How do I fix it? Thanks.
To make sure num is a whole number, without having to define all possibilities, use:
if (num % 1 == 0)
Why:
num==1 || 2 || 3 || 4|| 5
equals to:
(num==1) || 2 || 3 || 4|| 5
so if num is "1" (always a string type), the expression returns true, otherwise 2 (also a truthy value), eventually your if statement always succeeds.
How to fix:
// implicitly converts the string type into number type before comparison
// returns true if it is an integer-like string
num == Math.floor(num)
So you could do it like this:
if (num == Math.floor(num) && num > 0 && num < 6) {
// an integer-like string that meets the requirement [1, 5]
}
But remember, the num is still string type now. If you want a number, do:
num = +num
You should do
if (num == 1 || num == 2 || num == 3 || num == 4 || num == 5)
WRONG - otherwise it will compare 2 with 2 and says it's true for the 4 last 'if' parameters.
CORRECTO - any number in JS is considered as true.
You have to edit the "If" loop:
if (num == 1 || num == 2 || num == 3 || num == 4 || num == 5)
I was wondering if there was a quick way to test the equality of more than two values in js. Something similar to (= 6 6 6).
In the console, I tried things like...
1 == 1 == 1 == 1
true
2 == 2 == 2 == 2
false
0 == 0 == 0
false
0 == 0 == 0 == 0
true
...which was amusing, but also puzzling.
Is there a quick way of doing this in js?
Thanks.
The reason you got unexpected behavior is because we need to adjust your expectations in js a bit ;) 2 == 2 == 2 == 2 does 3 comparisons, all from left to right. The first comparison is the leftmost 2 == 2, which evaluates to true. After that we get the result of the first comparison being compared to (what is in this case) the 3rd 2. Ie, true === 2, which is false. And finally, we get false === 2, which is also false.
It might help to visualize it as such:
(((2 == 2) == 2) == 2)
I think in general a === b && b === c might be what you're looking for.
EDIT: Ah, and sorry I keep switching out the == for ===. It's just habit. And it's a habit I'd recommend. the === operator doesn't do type casting, so it evaluates the value proper, not a casted version of the value.
It's because true == 1 but true != 2
You can try:
function isEquals() {
var flag = true;
for(var i=1; i<arguments.length; i++) flag = flag && (arguments[i] == arguments[0]);
return flag;
}
isEquals(2,2,2); // true
or:
function isEquals() {
var ar = arguments;
return Array.prototype.every.call(arguments, function(a){return a==ar[0];});
}
Yes you can, but you need to use the "Logical Operators" like the && or || to check more than 1 statement like (x<1 && y>0).
You can use this as a quick easy reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators
If you have more than three values, it might be more convenient to create a function for use on an array:
function allEqual(arr) {
return arr.every(function (x, i) {
return i === 0 || x === arr[i - 1];
});
}
allEqual([1, 1, 1])
ES6:
function allEqual(...arr) {
return arr.every((x, i) => i === 0 || x === arr[i - 1]);
}
allEqual(1, 1, 1)
As an addition to #vp_arth's answer you could even add a method to the Array prototype
Array.prototype.isHomogeneous = function(){
return Array.prototype.every.call(this, function(c,i,a){ return c === a[0];})
}
So you could do
[1,2,3].isHomogeneous() = false
[1,1,1].isHomogeneous() = true