Javascript best practice to use undefined as boolean evaluation? - javascript

In this simple javascript code, method verify returns a string if conditions do not match, else undefined. I am using undefined value in 'if' clause. Is this common / acceptable javascript programming practice?
if (verify(text)) {
alert(text + " is not bar");
}
function verify(foo) {
if (foo + "" != "bar") return "foo is not same as bar";
}

Yes, since you know the verification outcomes will be either truthy (a non-empty string) or falsy (undefined), it's perfectly fine to use it like that.
Here's a list of truthy and falsy values in JS, you might find them handy: http://www.sitepoint.com/javascript-truthy-falsy/

It is a common practise but in my experience its better to be explicit. For instance, I prefer:
verify(text) === undefined
The way I would suggest is to make the 'verify' to return a boolean value. The reason for this, is if for whatever reason you have a verification method that returns 0 (zero) and you do if (verify), the condition will be false but 0 is actually a verified value.
I hope that helps.

Although this is technically possible and works fine in most cases, I personally find it better style to design functions so that they always return the same type. My IDE warns me about inconsistent functions:
and this warning should be taken seriously. In particular, it helps you avoid unpleasant surprises when you test your app:
// hmm...
function isZero(n) {
if(n == 0)
return true;
}
// let's test it
describe("test", function() {
it("isZero", function() {
expect(isZero(0)).toBe(true);
expect(isZero(1)).toBe(false); // FAILURE!
});
});

Related

Javascript: var1 == true && (var2 = true)

I see in the code I am working on often the following code style;
var1 == true && (var2 = true)
After some testing I figured it comes down to:
if (var1 == true) {
var2 = true;
}
Is this correct, or is there more to it? And why would anyone use this since the readability just dramatically reduces, since your assume at first glance it is just a check on two variables. So you really have to start looking at single or double equal sings and where the parentheses are, which just kinda, you know.. Just curious here..
Yes, this is equivalent. As far as I know, it is called short-circuit evaluation, describing the fact that the interpreter will return false for the whole boolean expression as soon as one of its parts is falsy.
Indeed, in your example it DOES reduce readability. But I think of it as just another tool in your toolbox you may use when you feel it could be useful. Consider the following:
return user && user.name;
This is one example when I tend to use it. In this case, I think it's actually more readable than
if (user) {
return user.name;
} else {
return undefined; // or null or something alike
}
UPDATE
I want to give you another example when I consider this kinds of constructs useful. Think of ES6 arrow functions like user => user.name. It does not need {} to open a body since it just has one line. If you wish to log something to the console (for debugging), you would end up having
user => {
console.log(user); // or something alike
return user.name;
}
You might as well use the shorter variant
user => console.log(user) || user.name
since console.log returns undefined after logging into the console, hence user.name is returned.
Yes, as you've mentioned there's more to it.
the first part var1 == true checks whether ther result is true or false.
if the condition is false the code after it doesn't get checked or evaluated and thus var2 doesn't get set to true.
But if the first part of the condition var1 == true is true which obviously is true, the second part of the conditional statement the part after && is checked.
now the second part of the condition is an operation it sets (var2 = true) which is kind of a truthy operation.
we could edit your code a little bit to help you understand the operation more clearly:
if( var1 === true && (var2 = true)){console.log('good');}
I hope this helps

Optimizing conditionals/if blocks, what is preferable from a performance point of view?

I am writing a JS library, and there are two things that have been on my mind for quite some time though.
Consider an option:
var option = { bool : true } ;
Now, imagine I do either
if(option.bool)
or
if(option.bool === true)
The first case, despite knowing for sure that it's either true or false, I imagine is the equivalent of:
var tmp = options.bool;
if ( tmp !== undefined && tmp !== null && ( tmp === true || tmp ... )
That means that to try the options.bool = true it has to check both undefined and not null, before testing for true.
Therefore the latter case should be more performant. However, the latter case, takes a considerably more characters and will lead to a larger lib, if repeated many times.
But maybe my understanding is incorrect.
Right now, even if I do:
var bool = window.t ? true : false;
if ( bool === true ) // I still have to check for true to 'have the optmimal version'?
Maybe the last case can be optimized by the compiler, but when it's a global option I imagine it's different?
Please share with me your thoughts on this.
The answer is simple. It's less about coding patterns and more about logic.
In this scenario there are always 3 possibilities and you need to cater for each of them.
Ie. 1. TRUE 2. FALSE 3. undefined
If the value is undefined then do you want it to fall under the true or false clause? OR should it be catered for differently?
Another important thing to remember is that if it is undefined then it will always execute the code in the false clause. Is that what you want?
If you know that the value will always be either true or false then I suggest that you still use the syntax == true as this is more readable. Someone browsing over the code would know that you are looking for the boolean value and not testing if the field has been set.
You have to think about these 3 cases every time you have a boolean in an if statement, so there is no 1 answer for you.

If true … else Shorthand

I know that the normal use case for this if statement is e.g.
var string = boolean ? "this" : "that";
I use jhint in my editor and when i try something like
boolean ? array.push("this") : array.slice("that",1);
jshint throws (W030) "Expected an assignment or function call and instead saw an expression"
So far the code always worked fine but maybe i was just lucky.
So my question is, why should i not use this pattern and what would be an alternative? Because writing
if(boolean){
array.push("this");
} else {
array.splice("that",1);
}
for such short instructions really give me the creeps.
thank you.
It is possible to wrap the ternary operator inside the void operator like this:
void(cond ? expr1 : expr2);
This achieves the desired result and passes JSHint. See JSFiddle and click JSHint button.
However, I recommend the following syntax:
if (cond) {
expr1;
} else {
expr2;
}
Because it is more readable. Just because JavaScript lets you do strange things does not mean that you should.
What it complains about is you misappropriating the conditional operator. It is an operator not a control structure. So it lives in the category of such things things as +,-,*,/. That means you expect the first operand to be a boolean and the second and third to yield a return value.
The whole thing is meant to be short for
if (boolean) {
string ="this" ;
} else {
string ="that";
}
It wants to return a value (which it can't in your case) and it expects you to use that value (which you don't). So the tenary if is not the thing to use for your case and as a result makes it far less readable.
You are using side effects in expressions to execute logic.
Indeed not very friendly code. It will work.
Just rewrite to distinct logic from expressions.
You can circumvent the jshint message using:
void(boolean ? array.push("this") : array.slice("that",1));
If you really want to use the ternary operater for this kind of operation in a clean way, then you can do it like this:
array[cond ? 'push' : 'slice'](cond ? "this" : "that", cond ? 1 : undefined);
or
array[cond ? 'push' : 'slice'].apply(null, cond ? ["this"] : ["that", 1]);
But anyway you may prefer a boring if statement.

Is it incorrect to use eval() within this function? Can I accomplish the same functionality without it somehow?

I'm trying to write a function I can use to test all for falsy values, keeping it concise since it will be run quite often serverside.
function is_falsy(val){
val = eval(String(val).toLowerCase());
return !!val;
}
I wonder if there's any way it could be done shorter, or what the possible negative implications of using eval() might be. JSBIN tells me it is "evil".
JSBIN
Assuming that val is a string that represents a JavaScript literal then we can take advantage of the fact that the only false-y values in JavaScript are:
0 (+ or -)
NaN
the empty string ('') or ("")
null
undefined
false
Thus, ignoring edge-cases (like 0.0) we could write it like so (a lower case can be performed as in the original code):
function is_falsey_literal (lit) {
if (['""', "''", "null", "undefined", "false", "0", "NaN"].indexOf(lit) >= 0) {
return true;
}
// Ideally there are more checks on numeric literals such as `-0` or `0.0`.
return false;
}
If needing to check a full expression then eval may "work" and is likely more practical when compared to writing a full JavaScript-in-JavaScript parser. For instance, in the above, the input string of (void 0) will be "true" although it evaluates to undefined which is definitely not a truth-y value.
Of course, perhaps the original data can be written/consumed such that there is no need for such a construct at all ..
There should never be any need to treat a string containing false or undefined as falsy. Doing so is inviting false positives (or false negatives) on possibly completely unrelated data.
Imagine what else would be treated as "falsy":
!true
!1
!!true
it's begging for mysterious bugs in your application further down the line.
The program flow should make sure that an undefined value actually arrives at your testing script as a literal undefined, not a string "undefined".
If you only want to test is falsy, then the below is enough.
function is_falsy(val){
return !val;
}
If you want to test whether a string is falsy value like 'false', then
function is_falsy(val){
try {
return !JSON.parse(String(val).toLowerCase());
} catch(e) {
return false;
}
}

JSLint Expected '===' and instead saw '=='

Recently I was running some of my code through JSLint when I came up with this error. The thing I think is funny about this error though is that it automatically assumes that all == should be ===.
Does that really make any sense? I could see a lot of instances that you would not want to compare type, and I am worried that this could actually cause problems.
The word "Expected" would imply that this should be done EVERY time.....That is what does not make sense to me.
IMO, blindly using ===, without trying to understand how type conversion works doesn't make much sense.
The primary fear about the Equals operator == is that the comparison rules depending on the types compared can make the operator non-transitive, for example, if:
A == B AND
B == C
Doesn't really guarantees that:
A == C
For example:
'0' == 0; // true
0 == ''; // true
'0' == ''; // false
The Strict Equals operator === is not really necessary when you compare values of the same type, the most common example:
if (typeof foo == "function") {
//..
}
We compare the result of the typeof operator, which is always a string, with a string literal...
Or when you know the type coercion rules, for example, check if something is null or undefinedsomething:
if (foo == null) {
// foo is null or undefined
}
// Vs. the following non-sense version:
if (foo === null || typeof foo === "undefined") {
// foo is null or undefined
}
JSLint is inherently more defensive than the Javascript syntax allows for.
From the JSLint documentation:
The == and != operators do type coercion before comparing. This is bad because it causes ' \t\r\n' == 0 to be true. This can mask type errors.
When comparing to any of the following values, use the === or !== operators (which do not do type coercion): 0 '' undefined null false true
If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
The === and !== operators are preferred.
Keep in mind that JSLint enforces one persons idea of what good JavaScript should be. You still have to use common sense when implementing the changes it suggests.
In general, comparing type and value will make your code safer (you will not run into the unexpected behavior when type conversion doesn't do what you think it should).
Triple-equal is different to double-equal because in addition to checking whether the two sides are the same value, triple-equal also checks that they are the same data type.
So ("4" == 4) is true, whereas ("4" === 4) is false.
Triple-equal also runs slightly quicker, because JavaScript doesn't have to waste time doing any type conversions prior to giving you the answer.
JSLint is deliberately aimed at making your JavaScript code as strict as possible, with the aim of reducing obscure bugs. It highlights this sort of thing to try to get you to code in a way that forces you to respect data types.
But the good thing about JSLint is that it is just a guide. As they say on the site, it will hurt your feelings, even if you're a very good JavaScript programmer. But you shouldn't feel obliged to follow its advice. If you've read what it has to say and you understand it, but you are sure your code isn't going to break, then there's no compulsion on you to change anything.
You can even tell JSLint to ignore categories of checks if you don't want to be bombarded with warnings that you're not going to do anything about.
A quote from http://javascript.crockford.com/code.html:
=== and !== Operators.
It is almost always better to use the
=== and !== operators. The == and != operators do type coercion. In
particular, do not use == to compare
against falsy values.
JSLint is very strict, their 'webjslint.js' does not even pass their own validation.
If you want to test for falsyness. JSLint does not allow
if (foo == null)
but does allow
if (!foo)
To help explain this question and also explain why NetBeans (from) 7.3 has started showing this warning this is an extract from the response on the NetBeans bug tracker when someone reported this as a bug:
It is good practice to use === rather than == in JavaScript.
The == and != operators do type coercion before comparing. This is bad because
it causes ' \t\r\n' == 0 to be true. This can mask type errors. JSLint cannot
reliably determine if == is being used correctly, so it is best to not use ==
and != at all and to always use the more reliable === and !== operators
instead.
Reference
Well it can't really cause problems, it's just giving you advice. Take it or leave it. That said, I'm not sure how clever it is. There may well be contexts in which it doesn't present it as an issue.
You can add this to the previous line to disable these warning.
// eslint-disable-next-line

Categories