I am using this "!!" comparation in order to compare with "undefined". However, is there any other way to do it?
isWidgetTemplatesLoaded: function(widgetName) {
return !!templates[widgetName];
}
Thanks
You could use typeof to check for undefined:
(typeof templates[widgetName] !== 'undefined')
typeof always returns a string. It returns "undefined" if the value of the variable is undefined or the variable does not exist.
You can use the typeof operator
typeof templates[widgetName];
else you can also use like this
if (templates[widgetName] === undefined) {
// rest of code
}
else {
// rest of code
}
To check for undefined you can just use the no-conversion equal/different operators:
if (x !== undefined) { ... }
if (y === undefined) { ... }
note however that this doesn't have the exact same meaning of !!. The double-negation for example returns true even for false, null, 0 or "" despite the fact that these values are not undefined.
By the way in Javascript you should basically always use === and !== instead of == and !=, unless you really need the crazy implicit conversion that equality/different operators do (and no one needs that). Good Javascript editors will warn you about any use of == or != as they are just bug-hiding places.
In the specific of your question code the !! logic seems wrong on a philosophical level because an empty template could be "" and this function would say that the template has not been loaded while instead it has been loaded and simply happens to be the empty string.
You could use the in operator, if you know, if the property exist with some value, other than undefined.
return widgetName in templates;
Related
One annoying thing about writing js app is that nested object can caused error and break down the entire app.
if(result.applicant._id === null || applicant_id !== result.applicant._id.toString()){
console.log('redirect user');
}
Given above code, it can be dangerous, what if result.applicant._id is null? then toString will be invalid because it can't be undefined.toString(). How to ensure toString() work in this case? I can do
if(result.applicant._id === null || applicant_id !== (result.applicant._id && result.applicant._id.toString())){}
but that's so unclean. I found that I'll have many duplication just for the sake of checking something exist using js.
Your version works without ever hitting undefined.toString() because the if condition will be short-circuited (short-circuitted?) as result.applicant._id === null would evaluate as true and never evaluate applicant_id !== result.applicant._id.toString().
The test is already there no need to add extra checks in this case.
Update Just realised the === will not match undefined.
Just change the first part to result.applicant._id == null which will match undefined and null.
if (result.applicant._id == null || applicant_id !== result.applicant._id.toString()){
console.log('redirect user');
}
I know you may end with linting warnings but in this case that's exactly what you want.
A bit of short-handing might give you the cleaner code you're looking for.
As long as 0 is not a valid application id:
const id = result.application._id || 0;
if(!id || applicant_id !== id.toString()){
// redirect
}
Edit: To explain - the || in the variable declaration assigns the value to the first truthy value - or the second. Therefore, if the value is undefined, it will fall to the second value (0) which is still falsey and will fail the check, but can still have .toString() called on it.
Edit 2: If your ids are just numbers (which is what it looks like) then you actually don't need to convert it to a string - just let JavaScript's coercion to the work for you by using != instead of !==
const id = result.application._id || 0;
if(!id || applicant_id != id){
// redirect
}
In JavaScript, 12 == '12' is true. 12 === '12' is false. Generally the advice is to use === unless you consciously want to take advantage of coercion, and this seems like a good case for it :)
🏄 The shortest way could be this:
.: UPDATED :.
const applicant = result.applicant || {}
if (applicant_id !== `${applicant._id}`) {
console.log('redirect user');
}
This question already has answers here:
Detecting an undefined object property
(50 answers)
Closed 5 years ago.
My question is about preventing an "variable is undefined" error more effiencitly.
e.g
If I use the following code:
if (array[index] != undefined)
{
if (array[index].id == 1)
{
// code
}
}
It will work fine. But, am I able to use
if (array[index] != undefined && array[index].id == 1)
{
// code
}
without getting an "variable is undefined" error, if array is undefined?
(I can't exactly test this in my code right now because I'm building a client-server application, and I'd have to alter many lines to try it, so I'm asking it here. I'm sorry if it's not appropriate)
&& will return true only if both the values of (a && b) a and b are truthy values.
If first operand(expression) is evaluated as false, second operand(expression) is not evaluated at all because the result would always be false
is better practice to use typeof to evaluate undefined variables:
if ( typeof array[index] !== 'undefined' && array[index].id == 1)
{
// code
}
Remember to check the string 'undefined' not the primitive value.
More info in MDN
No, if array is undefined, you will need an if statement that looks something like this:
if (array && array[index] !== undefined && array[index].id === 1) {
// do things
}
The first condition that if false will stop the evaluations of all the other conditions. The only way this will fail is if you are running you code in strict mode and have never declared var array
The if will return true only if all the conditions inside the paranthesis of if are true.
If any one of the expression is evaluated as false, The whole expression is evaluated as false.
If you have to check array itself is undefined then you will have to check typeof array also there. Something like this:
if(typeof array !== 'undefined'){
if ( typeof array[index] !== 'undefined' && array[index].id == 1)
{
// code
}
}
Yes, if the first condition fails, it will short-circuit and ignore the other conditions, like in any language.
I want to check this:
if ( typeof myVar != "undefined" && myVar != null )
...
In other words, I want to check if a variable has a defined value (including 0 or an empty string), but not undefined or null, which I interpret as valueless.
Do I have to do the two-part check each time or is there a handy shortcut?
If you want to allow 0 and "" as valid values and you want to cover the case of the variable might not even be delcared, but don't consider null a valid value, then you have to specifically check for undefined and null like this:
if (typeof myVar !== 'undefined' && myVar !== null)
...
A lot of values are falsey (they don't satisfy if (myVar) so you really have to conciously decide which ones you're testing for. All of these are falsey:
undefined
false
0
""
null
NaN
If you want to allow some, but not others, then you have to do a more specific test than if (myVar) like I've shown above to isolate just the values you care about.
Here's a good writeup on falsey values: http://www.sitepoint.com/javascript-truthy-falsy/.
If you know the variable has been declared and you just want to see if it's been initialized with something other than null, you can use this:
if (myVar != undefined)
...
Using only the != instead of !== allows this to test for both undefined and null via type conversion. Although, I wouldn't recommend this because if you're trying to discern between falsey values, it's probably better to NOT let the JS engine do any type conversions at all so you can control exactly what it does without having to memorize all the type conversion equality rules. I'd stick with this to be more explicit:
if (typeof myVar !== 'undefined' && myVar !== null)
...
If you want to know if it has any non-falsey value, you can of course do this (but that won't allow 0 or "" as valid values:
if (myVar)
...
The 2-part method. If you don't check for the typeof first, you'll end up with a reference error.
If you know the context of myVar, you should be able to do this:
if (this.myVar != null) {
...
}
if myvar could be undefined, calling it without the typeof check will throw an error.
And if it is defined as null (like myvar= element.lastChild for an element with no children) you will miss catching it if you just use typeof.
Well, null is a defined value... so if you want to make sure that the variable doesn't contain null, and isn't undefined you must do both checks.
Throughout many third-party libraries and best practices blogs/recommendations, etc... it is common to see syntax like this:
typeof x === 'object' (instead of typeof x == 'object')
typeof y === 'string' (instead of typeof x == 'string')
typeof z === 'function' (instead of typeof x == 'function')
If the typeof operator already returns a string, what's the need to type check the return value as well? If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary.
Under what circumstances will typeof not return a string literal? And even if there's some fringe case why is the additional type check being used for object, string, function, etc...
To answer the main question - there is no danger in using typeof with ==. Below is the reason why you may want to use === anyway.
The recommendation from Crockford is that it's safer to use === in many circumstances, and that if you're going to use it in some circumstances it's better to be consistent and use it for everything.
The thinking is that you can either think about whether to use == or === every time you check for equality, or you can just get into the habit of always writing ===.
There's hardly ever a reason for using == over === - if you're comparing to true or false and you want coercion (for example you want 0 or '' to evaluate to false) then just use if(! empty_str) rather than if(empty_str == false).
To those who don't understand the problems of == outside of the context of typeof, see this, from The Good Parts:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
It's subjective. You can just as easily turn this around, and ask, "Why would you use == when you don't expect implicit conversions?" Both work fine here, so use the one you feel expresses your intention better. Try to be consistent within a project.
There's no reason at all to favour === over == in this case, since both operands are guaranteed to be strings and both operators will therefore give the same result. Since == is one character fewer I would favour that.
Crockford's advice on this is to use === all the time, which is reasonable advice for a beginner but pointlessly paranoid if you know the issues (covered in other answers).
Because === is quicker than ==, due to omitting type coercion.
Sure it is probably a negligible difference but it is still there.
Triple equal operators are mostly used for variable type and value checking (all in 1 expression), also known as equality without type coercion.
Example:
var a = 1;
var b = 1;
var c = "1";
var d = "1";
alert (a === b); //True, same value and same type (numeric)
alert(c === d); //True, same value and same type (string)
alert(b === c); //False, different type but same value of 1
See Doug Crockford's YUI Theater on type coercion.
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
The most efficient reason for not using typeof and rather the === operator would be for type coercion (interpretation) between browsers. Some browsers can pass 6=="6" as true and some wouldn't (depending on the strictness of the JS interpreter) so by introducing type coercion would clarify this.
Also, it would bring the "Object-Orientativity" approach to it since JavasScript's variables are not type-based variables (i.e. variable types are not declared on compile time like in Java).
E.g. in Java, this would fail:
if ("6" instanceof Number) { // false
Hope I answered your question.
I'd like to know the difference (if any) between the following:
if( someDOMElement.someProperty )
{
...
if( someDOMElement.someProperty != null )
{
...
if( someDOMElement.someProperty != undefined )
{
...
Is one safer than the others?
Those will all do the same thing, and one isn't more error-prone than the others. Whereas if you were using !== rather than !=, the second two would only be true if the value really were null (the second one) or undefined (the third one), because the !== operator doesn't do coercion.
Javascript will coerce values during comparisons with != or ==, so for example:
alert(false == 0); // alerts "true"
alert(false === 0); // alerts "false"
The === and !== operators let you control that behavior. The rules for what coercions occur are detailed in the spec (and a bit complicated), but just a simple "is this thing not 0, "", null, or undefined?" can be written simply if (thingy) and it works well. 0, "", null, and undefined are all "falsey".
Sean Kinsey has a point about some host objects, though I think most if not all DOM element properties will be fine. In particular, I've seen COM objects exhibit some interesting behavior, such as if (comObject.property) evaluating true when if (comObject.property == null) also evaluates true. (In my case, it was COM objects exposed as part of the server-side API of a product I was using; I use Javascript server-side as well as client-side.) Worth being aware that that can happen. When you're dealing with Javascript objects and (in my experience) DOM objects, you're fine.
Assuming that someDOMElement is not null, no particular differences:
http://www.steinbit.org/words/programming/comparison-in-javascript
There would be a difference if you use !==
Depending on exactly what someDOMElement is then these can have very different results, and none of them are 'safe' to use if Host Objects are involved (objects implemented as ActiveXObjects for instance).
You should really use a method such as one of these
// use this if you expect a callable property
function isHostMethod(object, property){
var t = typeof object[property];
return t == 'function' ||
(!!(t == 'object' && object[property])) ||
t == 'unknown';
}
// use this if you are only looking for a property
function isHostObject(object, property){
return !!(typeof(object[property]) == 'object' && object[property]);
}
alert(isHostObject(someDOMElement, "someProperty"))
You can read more about proper feature detection at http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
depends on what you call a value.
if(someDOMElement && someDOMElement.someProperty !=undefined){
the property exists and has been set to a value other than undefined or null-
it may be 0, false, NaN or the empty string, as well as any truthy value
}