Javascript: Is there a reason to do "if (!a || (a && a.a))"? - javascript

Is there a special reason to do:
if (!options || (options && options.booleanCondition))
Instead of:
if (!options || options.booleanCondition)
I'm no javascript guru, so perhaps there's a special case or reason why the author of that code wrote it that way.

i don't see a reason to do
if (!options || (options && options.booleanCondition))
I'm no Guru but i'd stick to
if (!options || options.booleanCondition)
and save a check to the fact that options is true: in fact if options is not true the first condition is true and the second is never evaluated since it's an or condition.
That's what i think

Perhaps it's using a getter. This is a rediculous example but it can be the reason:
var o = {};
var i = 0;
o.__defineGetter__('options', function() {
return (i++) % 2 === 0 ? {booleanCondition: true} : null;
});
o.options; // Object first time
o.options; // null second time
This means:
if (!o.options || (o.options && o.options.booleanCondition))
!o.options is false (negating an object), but after that o.options is null (falsy) so then the check is mandatory.

if options.booleanCondition can change, then yes. If options is false, then the If condition will be true. If options is true, and boolean.Condition is false, then the If condition will be false. If option is true, and boolean.Condition is true, then the If condition will be true.
UPDATE
Actually, I guess it wouldn't be needed - since your simplification would be (if !true or true) if options is true, so the result would be same as (if true or true).

Related

Javascript if statement needs refactoring due to bad data

Javascript if statement needs refactoring due to bad data from my database.
I want a nicer way of doing this if statement:
if (typeof value === undefined || value === null || value === "" || value === 0) {
return false;
}
Is there a shorter way?
I look forward to your suggestions.
Is there a shorter way?
Only slightly:
if (value == null || value === "" || value === 0) {
...because both undefined and null are == null (and nothing else is).
Alternately, in ES2015 you could use a Set of values you want to filter:
let badValues = new Set([undefined, null, "", 0]);
then
if (badValues.has(value)) {
If you also are happy filtering out false and NaN, then you can just use
if (!value) { // Does more values than your question asks for, see note above
Note that your first condition is wrong: If you use typeof value then undefined must be in quotes, because typeof always returns a string.
You could even do something like this:
return Boolean(value);
Note that:
!!null === false
!!"" === false
!!0 === false
!!undefined === false
You can just write:
if (!value || !value.length) {return false}
if (!value) return false;
proof - >
console.log(!undefined, !null, !"", !0);
returns -> true true true true
console.log(!100, !"hello", !"0", !"false", !"true");
returns -> false false false false false
Javascript automatically transform into boolean other variables types in if statement, you can do something like this:
if (!value || !value.length) {
return false;
}
undefined, null and 0 are transformed into "false", meanwhile with .length, if it is 0 you will still have false, otherwise another number will be true.
Cheers
EDIT
for avoiding the object {length:0} to be parsed as empty, you can add:
if (!value || ((value instanceof Array || typeof value === 'string') && !value.length)) {
return false;
}

Null checking in Javascript (with ternary operator)

want to check null values. any() method returns null or array of matched result (actually there's a match() method inside which is returned).
$scope.isMobileBrowser = !isMobile.any() ? false : true;
If any() method returns null I want false to be assigned to $scope.isMobileBrowser variable, otherwise true. will the over mentioned snippet fail in any probable case? Is there any other more efficient workaround?
for more details of isMobile object:
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
Empty string is also a falsy value.
If any() returns an empty string, !isMobile.any() ? false : true will return false, but you probably want true.
This means your code is incorrect for this case.
I'd just do something like isMobile.any() !== null.
As per the any() function, you are returning value of the following expression:
(isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS()
|| isMobile.Opera() || isMobile.Windows())
Each of these functions can either return an Array or null as seen in the doc for match
So while evaluating the OR it will evaluate to the first truth value encountered and doesnt evaluate any further as the expression is already fit to be true. So, for example if the browser is android the expression evaluates to ["Android"]. If windows it will be ["Windows"]. If none of these, it will be null. Which makes it clear that any() can only return an Array or null.
isMobileBrowser should be true if it's any of these mobile browsers, which means isMobileBrowser should be true if:
any() evaluates to an Array
OR in other way:
If any() does not evaluate to null
which is:
$scope.isMobileBrowser = isMobile.any() instanceof Array;//looks messy
$scope.isMobileBrowser = (isMobile.any()).constructor === Array;//looks messy
$scope.isMobileBrowser = Array.isArray(isMobile.any());//looks messy
$scope.isMobileBrowser = Object.prototype.toString.call(isMobile.any())
=== "[object Array]";//looks messy
OR the other way:
$scope.isMobileBrowser = isMobile.any() !== null;
$scope.isMobileBrowser = !(isMobile.any() === null);
isMobileBrowser = !(Object.prototype.toString.call(isMobile.any())
=== "[object Null]");//looks messy
So we just discussed different ways to check for null and Array. You have two possible sets of outputs
null value which is always false
An Array which is always true (You can check this empty array scenario although that doesn't apply here)
So you can simply do the following to convert those to exact boolean without worrying much:
isMobileBrowser = Boolean(isMobile.any()); //to convert value to boolean
isMobileBrowser = !!isMobile.any(); //another way to convert to boolean
//!!["Android"] is true
//!!null is false
#rossipedia explains the !! well in his answer.
A compact way of representing what you want would be:
$scope.isMobileBrowser = !!isMobile.any();
The !! there does two things:
The first ! evaluates the "truthiness"1 of the return value of isMobile.any() and then negates it.
The second ! negates that value again.
So what you end up with is false if .any() returns null, otherwise true.
However, this may fail in edge cases where .any() returns something that is "falsy". In that case, checking for null specifically is what you want:
isMobile.any() !== null
1: "Truthiness":
In JavaScript, a truthy value is a value that translates to true when evaluated in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, "", null, undefined, and NaN).
From MDN
Try this:
$scope.isMobileBrowser = isMobile.any() === null;

javascript multiple OR conditions in IF statement

I think I'm missing something basic here. Why is the third IF condition true? Shouldn't the condition evaluate to false? I want to do something where the id is not 1, 2 or 3.
var id = 1;
if(id == 1) //true
if(id != 1) //false
if(id != 1 || id != 2 || id != 3) //this returns true. why?
Thank you.
With an OR (||) operation, if any one of the conditions are true, the result is true.
I think you want an AND (&&) operation here.
You want to execute code where the id is not (1 or 2 or 3), but the OR operator does not distribute over id. The only way to say what you want is to say
the id is not 1, and the id is not 2, and the id is not 3.
which translates to
if (id !== 1 && id !== 2 && id !== 3)
or alternatively for something more pythonesque:
if (!(id in [,1,2,3]))
Each of the three conditions is evaluated independently[1]:
id != 1 // false
id != 2 // true
id != 3 // true
Then it evaluates false || true || true, which is true (a || b is true if either a or b is true). I think you want
id != 1 && id != 2 && id != 3
which is only true if the ID is not 1 AND it's not 2 AND it's not 3.
[1]: This is not strictly true, look up short-circuit evaluation. In reality, only the first two clauses are evaluated because that is all that is necessary to determine the truth value of the expression.
When it checks id!=2 it returns true and stops further checking
because the OR operator will return true if any one of the conditions is true, and in your code there are two conditions that are true.
This is an example:
false && true || true // returns true
false && (true || true) // returns false
(true || true || true) // returns true
false || true // returns true
true || false // returns true

Any value that makes a JavaScript comparison always true?

Is there any JavaScript value that makes a comparison always true?
Example with lower than operator:
true < 10 true
false < 10 true
null < 10 true
Example with greater than operator:
true > 10 false
false > 10 false
null > 10 false
What I'm looking for:
alwaysTrue < 10 true
alwaysTrue > 10 true
I want to use this to make one part of an if statement return true by default and true or false when the first comparison value is changed.
This is probably not existent but I want to be completely sure.
You may want to consider leveraging "or" in your condition with another variable that can trump whether it returns true or not.
returnTrue || testVariable < 10
This will always return true when returnTrue is set to true, otherwise it will fall back on the comparison. If you are just looking for a change in a variable you can do so by storing the old value. If you know it will never be null you can check on this, otherwise you can use the the "or" with a flag similar to above.
oldValue === null || currentValue === oldValue
I'm not exactly sure if this is what you are asking, but this is a way of doing it with a few more statements:
var rtn = true;
if (oldCompareValue != newCompareValue) {
// next you'll want to insert your return expression
// i'm not sure you've specified what this should be
rtn = (newCompareValue > 10)? true: false;
}
return rtn;
You can also do this using the AND operator as you've requested:
rtn = true;
if ((oldCompareValue != newCompareValue) && true) {
rtn = (newCompareValue > 10)? true: false;
}
return rtn;
The if statement does the following for us:
if oldCompareValue is the same as newCompareValue then the whole statement is false
if oldCompareValue is not the same as newCompareValue then the whole statement is true
In either case the right part of the test expression always evaluates to true, and you'll only enter the if when the left part passes as well. However, keeping that true in place seems excessive to me.
Once you got you're logic in place this can go into one line.

Javascript or operator not working

var strExt = GetAttributeFromItemTable(itemTable, "Ext", "FileType");
I did a alert for strExt and it resolves.
if (strExt!='wav')
{
// this works
}
if (strExt!='wav' || strExt!='mp3')
{
// this does not work.
}
Your logic is flawed:
if your variable strExt was equal to 'wav' it would not be equal to 'mp3', and versa-visa.
Please explain your desired results more clearly.
I think what you're trying to say is something like (neither 'wav' nor 'mp3'):
if ( !( strExt == 'wav' || strExt == 'mp3' ) )
which is logically equivalent to (not 'wav' and not 'mp3'):
if ( strExt != 'wav' && strExt != 'mp3' ) )
|| says: if any condition is true, It'll return true, without looking at the ones after it.
So true || false is true, false || true is true.
In your case, you say "if strExt is not equal to wav and is not equal to mp3, then execute the code". In case that one of them is true, it executes.
I'm thinking that you're looking for the && symbol. The logical and says "I'll return true only if every condition is true" - when it hits a false, it returns false.
What I think your code should look like:
if (strExt!='wav' && strExt!='mp3')
I would expect the result of the second expression to be True regardless of the value of the string strExt (any extension is either not equal to "wav" or not equal to "mp3"). What do you expect?
Are you certain you don't mean a Boolean AND instead of an OR ("extension is neither 'wav' nor 'mp3'")?
just add the another parenthesis, like so:
if ((strExt!='wav') || (strExt!='mp3'))
{
// this does not work.
}
The logic behind this makes no sense wouldn't you want to do:
if ((strExt !== "wav") && strExt !== "mp3") {
}
AND instead of OR makes more sense in this situation.
If you want to get into second if, when strExt is not equal to both 'wav' and 'mp3' you need to use an && operator.
if (strExt!='wav' || strExt!='mp3')
when strExt='wav' => strExt!='wav' = false; strExt!='mp3' = true => false or true = true and gets into if statement and is the case is similar when strExt='mp3' .

Categories