I'm writing a script to be executed when my body element hasn't got any of the following classes:
a OR b OR c AND d
I tried this, but it doesn't seem to do the trick:
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || ((!($('body').hasClass('c')) && (!$('body').hasClass('d'))))) {
}
UPDATE
This seems to work:
if (!($('body').hasClass('a') || $('body').hasClass('b') || $('body').hasClass('c') && $('body').hasClass('d'))) {
}
use
$(function(){
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || !($('body').hasClass('c') && $('body').hasClass('d'))) {
}
});
You are looking for a body that doesnt have any of the classes, so you need to use &&. Heres what happens:
if(hasclass(a) || hasclass(b)) = if(true OR false) = if(true)
Above the OR operator || means that once it hits a true evaluation, it will execute your if-block.
if(hasclass(a) && hasclass(b)) = if(true AND false) = if(false)
Here the AND operator && means that once you hit a false evaluation, you block won't be executed.
You want the last thing to happen, since you want it to have neither of the classes. Learn how to play with these operators as they can be very confusing. As long as you remember that the AND operator will execute only if all statements are true and the OR operator will only execute if one of the statements is true. Nested operators work the same, so if((a = b && b = c) || (a = c)) will execute if a,b and c are the same OR when a and c are the same, but not when a and b are the same or a and c are the same.
More on expression and operators (specifically Bitwise and a must read): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators
Related
Given the following problem that I need to solve about nested logic, I saw the following possible solution online but I hadn't seen code organized like this and can't help to figure it out. It looks like a different approach I hadn't seen to "if" and "else if" statements, so I would like to understand what's going on. Thank you.
let fine = 0;
const [actual, expected] = input.split('\n').map(item => {
const [day, month, year] = item.split(' ').map(Number);
return {
day,
month,
year
};
});
(
actual.year === expected.year &&
actual.month === expected.month &&
actual.day > expected.day
) && (fine = (actual.day - expected.day) * 15);
(
actual.year === expected.year &&
actual.month > expected.month
) && (fine = (actual.month - expected.month) * 500);
(actual.year > expected.year) && (fine = 10000);
console.log(fine);
}
The code takes advantage of something called short-circuit evaluation, which isn't unique to JavaScript. In a broad sense, short-circuit evaluation means only evaluating a boolean expression if it is necessary to determine the ultimate outcome. It also takes advantage of the fact that in JS, assignment operators act as expressions.
Here's an example of what I mean:
let x;
console.log(x = 2) // 2
What this means is that you can have an assignment expression at the end of a list of conditions to act as an if statement. Due to short circuit evaluation, the assignment expression will only be evaluated if the ultimate true/false value of the full expression is not predetermined by the conditions.
let x;
(false && x = 1) // does nothing, false && ___ = false
(true || x = 2) // does nothing, true || ___ = true
(true && x = 3) // sets x = 3, true && ___ evaluates ___
(false || x = 4) // sets x = 4, false || ___ evaluates ___
JavaScript has short-circuit boolean evaluation, and the code in your question uses that extensively.
Take for example:
a() && b(); // if (a()) b();
Because both a() and b() need to evaluate to a truthy value for the entire statement to be considered true, JavaScript will not evaluate b() if a() already evaluates to a falsy value.
Similarly:
c() || d(); // if (!c()) d();
Because only one of c() or d() needs to evaluate to a truthy value for the entire statement to be considered true, JavaScript will not evaluate d() if c() already evaluates to a truthy value.
This can be used to implement logical branching, much like an if-else structure, although in most cases it does adversely impact the code's readability.
Nothing big changes in your code.
Heare simple syntax with the conditional operation in javascript var varname = condition ? true part code : false part code.
let fine = 0;
const [actual, expected] = input.split('\n').map(item => {
const [day, month, year] = item.split(' ').map(Number);
return { day, month, year };
});
fine = (actual.year === expected.year && actual.month === expected.month && actual.day > expected.day) ? ((actual.day - expected.day) * 15) : 0;
fine = (actual.year === expected.year && actual.month > expected.month) ? ((actual.month - expected.month) * 500) : 0;
fine = (actual.year > expected.year) ? 10000 : 0;
console.log(fine);
Something more
Using the traditional if statement I can do this:
if(a===0 || b===0) {console.log('aloha amigo')};
But when I try to do something the same thing with a ternary operator, like this:
a===0 || b===0 && console.log('aloha amigo')
I just get errors about unexpected ||.
According to this answer: Precedence: Logical or vs. Ternary operator, we can do it using
condition1 || condition2 ? do if true : do if false
(Sorry I'm not sure how to call the ? : symbols in this case), but I'm not sure how to get it running using && (It means only run the code if returned true).
I created a codepen to test it easily. Here's the whole code:
var a = 0;
var b = 1;
a===0 || b===0 ? console.log('Works here') : console.log('And here');
a===0 || b===0 && console.log('Doesn\'t work here');
a===0 && console.log('The && works for a single test');
Here's the link
Just take parenthesis to prevent operator precedence of && over ||
(a === 0 || b === 0) && console.log('aloha amigo')
Without parenthesis, you get (now with to show the precedence) a different result.
a === 0 || (b === 0 && console.log('aloha amigo'))
^^^^^^^ first evaluation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second evaluation
What's the point of having this logical operator like this: r == 0 && (r = i);?
function do()
{
var r = 0;
var i = 10;
r == 0 && (r = i);
}
is this the same as:
if (r==0)
{
r=i;
}
What always helps me is translating it to words
var r = 0;
var i = 10;
r == 0 && (r = i);
translates to
set variable r to zero
set variable i to ten
if variable r equals zero AND the return of the following statement "set variable r to value of variable i"
do nothing, but r is now 10.
so in short, let's forget about 1 and 2.
In javascript the execution flow in a boolean comparisan is to stop execution of if statement parameters if any part from the && fails.
An boolean comparisan will execute from left to right.
1 == 1 && 2 == 3 && (r = i)
it will pass 1 == 1 fail on 2 == 3 and never reach the assigment operation.
Basically it's a shorthand for:
if(r == 0) {
r = i;
}
Simple yes r == 0 && (r = i);is same as
if (r==0)
{
r=i;
}
Just tested the speed of the code and the && is little bit faster (almost negligible).
Coming to the actual question, I found the place of using && instead of if us literally short hand code of later. However I never use the code as it highly kill the readability of code reader.
As docs says
Logical operators are typically used with Boolean (logical) values. When they are, they return a Boolean value.
But what we are seeing here is an assignment to the a variable based on other. Of course the code works but I believe, this is just a mis usage of the convention.
It is the same, in terms of logic and control flow.
It is shortening lines of code (code golf) by (ab)using short-circuit behavior.
The StackExchange page for code golf is https://codegolf.stackexchange.com.
For even shorter code, you could use a logical OR as default operator.
r = r || i;
Or
r || (r = i);
I've been reading some of the answers here and I've come up with this summary.
Short Summary
Condition on r: Assign i to r, in case r is null:
r = r || i
Or
r || (r = i)
Condition on i: Assign i to r, in case i is not null:
i && (r = i)
Or
r = i || r
More Examples
a || (Do Something) // Means: if `a` is `null`
!a || (Do Something) // Means: if `a` is **not** `null`
a && (Do Something) // Means: if `a` is **not** `null`
!a && (Do Something) // Means: if `a` is `null`
It is indeed the same, and a technique often used by minifiers to collapse code. In this case, you can even use an ! in order to do the if as you are comparing without typecheck:
!r && (r = i);
Or use an || operator for this assignment:
r = r || i;
If you want to keep your code clear, use an if tho.
Consider you have something to print only when r=0 and i=10. then && will be use full like.
if(r==0 && i==10){
console.log('its good practice')
}
if we use seperate, like
if(r==0){
if(i==10){
console.log('its bad practice')
}
}
what will you do if you have lots of condition to check.? i suggest you to use first one.
I've found unknown for me code construction on JQuery site. After some formatting it looks like:
function (a,c) {
c==null && (c=a,a=null);
return arguments.length>0
? this.bind(b,a,c)
: this.trigger(b)
}
What does the first line of the function mean? Is it any trick or standard JS code construction?
It's a trick that uses boolean short-circuit evaluation to only do the second half if the first evaluates to true. Perl has this commonly:
<something> or die
where if the first statement failed, the program ends.
Read it as
if (c == null) { c = a; a = null; }
That's an ugly way to write
if(c==null) {
c = a;
a = null;
}
This utilizes the fact, that the second part of boolean && will be executed if, and only if the first part evaluates to true.
The expression uses two JavaScript features :
short circuit evaluation of boolean operators: in statement context, a && (b); is equivalent to if (a) (b);
the comma operator to group assignment expressions: in statement context, a=b,b=c; is equivalent to { a=b; b=c }
As a result the expression is equivalent to:
if (c == null) {
c = a
a = null
}
I understand that in JavaScript you can write:
if (A && B) { do something }
But how do I implement an OR such as:
if (A OR B) { do something }
Use the logical "OR" operator, that is ||.
if (A || B)
Note that if you use string comparisons in the conditions, you need to perform a comparison for each condition:
if ( var1 == "A" || var1 == "B" )
If you only do it in the first one, then it will always return true:
if ( var1 == "A" || "B" ) //don't do this; it is equivalent to if ("B"), which is always true
The official ECMAScript documentation can be found here
Worth noting that || will also return true if BOTH A and B are true.
In JavaScript, if you're looking for A or B, but not both, you'll need to do something similar to:
if( (A && !B) || (B && !A) ) { ... }
if (A || B) { do something }
Use the || operator.
|| is the or operator.
if(A || B){ do something }
here is my example:
if(userAnswer==="Yes"||"yes"||"YeS"){
console.log("Too Bad!");
}
This says that if the answer is Yes yes or YeS than the same thing will happen
One can use regular expressions, too:
var thingToTest = "B";
if (/A|B/.test(thingToTest)) alert("Do something!")
Here's an example of regular expressions in general:
var myString = "This is my search subject"
if (/my/.test(myString)) alert("Do something here!")
This will look for "my" within the variable "myString". You can substitute a string directly in place of the "myString" variable.
As an added bonus you can add the case insensitive "i" and the global "g" to the search as well.
var myString = "This is my search subject"
if (/my/ig.test(myString)) alert("Do something here");
You may also want to filter an IF statement when condition1 equals 'something' AND condition2 equals 'another thing' OR 'something else'. You can do this by placing condition2 in another set of brackets eg...
if (condition1 === 'x' && (condition2 === 'y' || condition2 === 'z')) {
console.log('do whatever')
}
If condition2 is NOT in it's own brackets then condition1 has to be x AND condition2 has to be y for the function to trigger...
... but it will also trigger if condition2 is z, regardless of what condition1 is. Which may be okay depending on your use case, but something to be mindful of.