How can this conditional be shortened? - javascript

if (!this.initialized || (typeof this.activeId !== 'undefined' && options.qualification_id !== this.activeId)) {
//Stuff
}
I want to execute code if the this.initialized flag is false or this.activeId value isn't the same as options.qualification_id. I have to check if this.activeId is defined or not because Javascript will return true in the case of undefined !== this.activeId. The above is the conditional I've come up with, but I hate how long it is. What would be the shortest way to write it?

If the valid values for this.activeId when it's defined are all truthy (e.g. it can't be 0, false, or null), you can use:
if (!this.initialized || this.activeId && options.qualification_id != this.activeId)

Let's see what you can do to shorten this
(!this.initialized || (typeof this.activeId !== 'undefined' && options.qualification_id !== this.activeId))
Well first, you can remove the inner parenthesis. According to the operator precedence table, logical AND has a "higher precedence" than logial OR. In other words the parenthesis will be added for you by the interpreter. So, your condition becomes:
(!this.initialized || typeof this.activeId !== 'undefined' && options.qualification_id !== this.activeId)
Not much better. Another thing you can do is take advantage of JS type conversion. undefined values are falsey (are evaluated to false), your condition can become:
(!this.initialized || this.activeId && options.qualification_id !== this.activeId)
However, this may insert a silent bug since an activeId of 0 will also be evaluated to false. You can solves this using the in operator which checks to see if the property exists on the object or on one of its prototypes (To make sure the property doesn't come from one of its prototypes you can use the hasOwnProperty method instead).
(!this.initialized || 'activeId' in this && options.qualification_id !== this.activeId).
Now to be honest, this doesn't look so much better to me. As a rule, whenever the line becomes too long, just split it in multiple lines to increase readability.
var qualificationIsDifferent = options.qualification_id !== this.activeId;
var isNotActive = this.hasOwnProperty('activeId') && qualificationIsDifferent;
var shouldDoStuff = !this.initialized || isNotActive;
if ( shouldDoStuff ) { ... }
Note that by using the above approach you lose some of the benefits of the short-circuit evaluation.
It really depends on your goal, sometimes more verbose means more readable.

Related

!fullResponse?.response?.is_complete does not act as it supposed to do

I am having an issue to understand this:
!fullResponse?.response?.is_complete
I was thinking it is the same as
fullResponse &&
fullResponse.response &&
'is_complete' in fullResponse.response &&
!fullResponse.response.is_complete
but it is not and it breaks my code specially when is_complete does not present in fullResponse.response
Can anyone explain what this does : !fullResponse?.response?.is_complete and if there is a way to make it act as below?
fullResponse &&
fullResponse.response &&
'is_complete' in fullResponse.response &&
!fullResponse.response.is_complete
The part you've probably misunderstood is the precedence of these operators. Your code actually boils down to:
!(
// vvvvvvv--- `== null`: either null or undefined
(fullResponse == null) ? undefined
:(fullResponse.response == null) ? undefined
:fullResponse.response.is_complete
)
So, when either part of your lookup short-circuits with an undefined, it runs right into the negation and gets converted to true.
If you just want to return false in case of a short-circuit, then it's as easy as:
// vvvv--- this will turn into false
!(fullResponse?.response?.is_complete ?? true)
However, if you want undefined in this case, it's easier with a variable:
const isComplete = fullResponse?.response?.is_complete
isComplete === undefined ? undefined : !isComplete
If you can't do that, you'll have to repeat the lookup:
fullResponse?.response?.is_complete === undefined ? undefined : !fullResponse?.response?.is_complete

Why checking undefined type instead of just value?

I got recently such legacy code:
if (typeof value != "undefined" && value.someOperation()) { }
I understand that its preventing undefined object issue, however isn't simple to do such thing:
if (value && value.someOperation()) { }
Is somewhere in deep javascript a hack or some situation that it would not work at all? There is no possible to get 0 or false instead of that object here. I wonder if I can change the first expression to the second one and I wouldn't break anything.
In this line
if (typeof value != "undefined" && value.someOperation()) { }
typeof value != "undefined" is evaluated to false if and only if value is either null or undefined. However, if the value is either 0 or false then it will evaluate to true, and hence move on to second condition value.someOperation().
There is no possible to get 0 or false instead of that object here.
If the value of value cannot be 0 or false, even then you might want to check value.someOperation before checking value.someOperation() since value.someOperation() it may give following error
TypeError: undefined is not a function
In fact, in both cases you might want to check if value.someOperation first before value.someOperation() i.e.
if (value && value.someOperation && value.someOperation()) { }
or
if (typeof value != "undefined" && value.someOperation && value.someOperation()) { }

How to easily check if undefined in javascript object?

Assuming I have a javascript object "myobject" that just contains an empty object "{}".
I ideally in my code I want to do the following:
if (theobject[keyvar][subkeyvar]) {
// do something
}
The issue now is that because keyvar and subkeyvar do not actually exist within the object, it fails and comains that the properties are undefined. What is the simplest/least lines of code/best way to be able to do have it just "know it is undefined" and continue to execute the //do something or not without crashing?
I dont want to get too carried away with checking like:
if( keyvar in theobject ) {
if(subkeyvar in theobject) {
if.....
}
}
if (typeof theobject[keyvar] !== "undefined" && typeof theobject[keyvar][subkeyvar] !== "undefined") {
// keyvar and subkeyvar defined
}
first we check if keyvar typeof is undefined and then if subkeyvar is undefined and if they are both defined typeof theobject[keyvar] !== "undefined" && typeof theobject[keyvar][subkeyvar] !== "undefined" is true.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
you can try this :
if (theobject[keyvar] && theobject[keyvar][subkeyvar]) {
// do something
}
If they both can possibly be undefined, you have to test one, then the other.
if (theobject[keyvar] && theobject[keyvar][subkeyvar]) {
This will of course fail on a key containing 0 or "" (or several other falsey but not undefined values) so you may want to use typeof on the second test.
Try:
if (theobject[keyvar] !== undefined && theobject[keyvar][subkeyvar] !== undefined) {
// do something
}
Since the && operator is used, the if will not check the second value if the first value is falsey, so you will never get the 'properties are undefined` error
theObject.hasOwnProperty(keyvar) && theObject.hasOwnProperty[keyvar].hasOwnProperty(subkeyvar)

comparing against undefined

Is it unsafe to compare a variable against undefined?
if(foo == undefined)
vs
if(foo == 'undefined')
Is the first example sufficient? Or should it be something like
if('undefined' in window){
//compare against undefined
} else {
//compare against 'undefined'
}
since undefined exists on the window object? Will it exist in all browsers? Or should I simply compare to == 'undefined'? I've found some similar questions on SO, but no answers regarding the existance of the undefined property on the window object.
I think you're getting mixed up between foo == undefined and typeof foo == "undefined".
Both will yield the same result unless the variable undefined has been set to something else in the current scope. In this case, foo == undefined will compare against that, where-as typeof foo == "undefined" will still resolve correctly.
var undefined = 4;
var reallyUndefined;
reallyUndefined == undefined; // false
typeof reallyUndefined == undefined; // true
Whether it's a real world scenario that undefined will ever be set to something else is debatable, and I'd question the validity of the library/ code that does that... Because of this however, it's deemed good practise to always use typeof foo === "undefined".
I'd also be wary about using foo == undefined against foo === undefined (note the triple equals, which does not use type-coercian, compared to == which does).
Using ==, you run the risk of things like null == undefined; // true, where-as null === undefined; // false. This is a good example of why you should always use ===.
tl;dr: typeof foo === "undefined";
I'd suggest you to use typeof instead:
if (typeof foo == "undefined") {
// ...
}
Note, that typeof returns a string, so you should always compare it with string value.
if (foo === undefined)
Is safe
There are several ways to do this, but the easiest I've found is this:
if(foo === undefined){
//do stuff
}
If you have complete control of all the code and you know you won't have to worry about someone mucking about with undefined then it is safe to compare against it.
alert(window.foo === undefined);
On the other hand, if you want to be a bit more paranoid, you can do a typeof check which can't be affect by the outside word
alert(typeof window.foo == 'undefined')
The third option is to have your own, local, undefined variable.
function testme(a, undefined) {
alert(a === undefined); // Will be false.
}
testme(10);

php style function check in javascript

I don't recollect exactly what its called but php checks and exists as soon as it finds one false value in a function, like so :
// php
if(isset(a["hi"]) && isset(a["hi"]["hello"])) {
}
here if a["hi"] is not set, it will not bother to check the next a["hi"]["hello"].
to check something like this in javascript you'd need to nest
// js
if(typeof(a["hi"]) != "undefined") {
if(typeof(a["hi"]["hello"]) != "undefined") {
}
}
Can we do php style lazy checking in javascript?
(I may not be using the best method to check if an element exists in a multi-dimentional array, if there is a succinct way of doing this, would love to know.)
thanks!
You could use in to check property existence.
if(a && ('hi' in a) && ('hello' in a['hi'])) {
}
if(a.hi === undefined && a.hi.hello === undefined) {
if you know that a.hi can never be a falsey value (null / false / 0) you can do
if(!a.hi && !a.hi.hello) {
Checking the typeof a variable for the string "undefined" is equivalent to using === to check whether the variable is the same data type as the undefined keyword. You can therefore reduce the nested if statements to a single statement:
if(a.hi !== undefined && a.hi.hello !== undefined) {
// do something with a.hi.hello
}
It's worth noting that the statement above assumes that a is not null when the if statement takes place which could cause errors. It also holds true that if you require a.hi.hello to be present for the if statement to evaluate, then you can use falsy checking for a and a.hi as they would need to be object types for (which are non-falsy):
if(!!a && a.hi && a.hi.hello !== undefined) {
// do something with a.hi.hello
}

Categories

Resources