How do I write a clean conditional statement - javascript

This may be a dumb question but what is an easy way to write a clean condition statement, for example lets say if I have a conditional statement where I only want it to happen before a block of code if it meets the requirement and if it doesn't then I want it to happen after the block of code. But it must happen in that order
EDIT
This code is NOT broken.. I was simply asking if there was a better way of structuring this conditional statement and I found out that putting the //random code in a helper method and combining the two if's into an else if would solve it. See my answer below.
if(number === 250){
// sameMethod()
}
//random code
if(number !== 250){
// sameMethod()
}
Solution
function helper() {
//random code
}
if(number !== 250){
helper()
// same code
} else {
// same code
helper()
}

if(number == 250){
// sameMethod()
}
//random code
if(number != 250){
// sameMethod()
}
For this, and based on the information at hand, I would recommend keeping the code as is. The way you have written this code, an if-else block would have a serious impact on the flow of your application.
Assume that randomCode is a method call, which performs the next operation:
function randomCode() {
this.number += 5;
}
and you start the code with the state of your application having the value of number as 245.
if ( number == 250 ) { // conditions 245 == 250 evaluates to false
// sameMethod -> will not be executed
}
randomCode(); // increases the value of number with 5
if ( number != 250 ) { // condition 250 != 250 evaluates to false
// sameMethod -> will not be executed
}
Just slapping an if-else, like this:
if ( number == 250 ) { // condition 245 == 250 evaluates to false
// sameMethod
} else {
randomCode();
// sameMethod -> here it will be executed, even though number now is 250. Change in behaviour
}
So, there are two things to consider: either the example code you posted was the correct flow, making it correct (but might end up in executing sameMethod twice, or not at all, since the value of number could be altered in the randomCode part, or both sameMethod and randomCode have to be executed (exactly) once, depending on that condition.
If so, the original (pseudo?) code was faultive, but the result would indeed come to:
if ( number == 250 ) {
sameMethod();
randomCode();
} else {
randomCode();
sameMethod();
}

This is where monads and all that jazz show their ugly mugs.
Assuming you are talking about java, you could for example write a runSequentially method that results in letting you write:
runSequentially(() -> sameMethod(), () -> {
// random code
}, number != 250);
Where runSequentially will first run the first Runnable, then the second Runnable - unless the condition is false, in which case it runs the second, then the first.
In java, this is not, however, local mutable variable, checked exception, and control flow transparent which are sufficient downsides that I'm not sure this is a good idea. Especially considering that apparently execution order matters which usually suggests mutating state. But, if you insist, it'd be something like:
public static void runSequentially(Runnable a, Runnable b, boolean flipOrder) {
if (flipOrder) { b.run(); a.run(); }
else { a.run(); b.run(); }
}
Javascript is a lot more laissez-faire (and a totally different language; did you tag it because perhaps you were unaware that 'java' and 'javascript' are completely unrelated? It's a common mistake - in that case, disregard this bit), and doesn't suffer from the transparency issues as much. Javascript has no checked exceptions, javascript lets you mutate outer state (there are some WTFs in javascript-the-language about this, but that's a separate issue). The biggest issue is control flow (you can't as easily break/continue loops in the 'outer' code from within these closures).
Going back to java for a moment, using lambdas (closures) in contexts where:
The lambda is run 'in-line', that is, you pass the lambda to some method, and once that method returns, the lambda is 'forgotten about' by said method: That method did not store the lambda in a field, did not pass it to another thread, did not pass it to other code that is going to store it in a field or pass it to another thread).
The code in the lambda is not designed 'functional style' (e.g. it mutates state or does a bunch of I/O), then
you're probably messing up. Lambdas really suck in that environment, those transparency issues are grating then. Note that if the lambda does 'travel' (is stored / moved to another thread), that lack of transparency is in fact a great thing because those 3 'transparencies' become bizarre braintwisters - best to just not allow them.
That's why I recommend against this, if you're writing java. But now you know how one would.

Thanks for all the advice, I should've been more clear about the language since I thought this was a fairly simple solution that might work in both Java and Javascript. I ended up just putting the "random code" in a helper function.
function helper() {
//random code
}
if(number !== 250){
helper()
// same code
} else {
// same code
helper()
}
Basically the idea was that, the order of which block of code that gets executed mattered depending on a fixed variable. It was messy without a helper function due to duplicated code so this simple solution fixed it. Let me know if you guys think of a more clever way! Thanks

Related

Micro optimization: Returning from an inner block at the end of a function

In languages such as javascript or (maybe?) lua, all functions by default are treated as if they had a return statement at the end:
function() {
// do
return;
}
Is equal to
function() {
// do
}
I'm wondering if returning from an inner block at the end of the function changes anything in the core, the compiling process, the VM.
function() {
if (condition) {
return;
}
// end of function
}
Same question applies to breaking a loop:
function() {
for ( loop ) {
return;
}
// end of function
}
Does the machine "look" for anything when a loop is broken, or a condition check has ended?
This is not a stylistic question, please don't tell me to make code readable.
TL:DR / optimization advice: you don't need to do anything special to gain performance. if(condition) return inside an inner loop is typically at least as efficient as an if(condition)break; to reach the end of the function.
Putting nested loops inside a function so you can use a return as a multi-level break is a good way of being able to express the logic efficiently without a goto, easy for humans and easy for compilers/interpreters.
Making loop conditions more complicated to avoid multiple return statements in one function is not helpful for performance.
Generally no, a return in the middle of a function is not fundamentally different or more or less efficient than reaching the implicit return at the end. And an explicit return at the bottom of a function isn't special either.
(We're talking about void functions that never return a value, I assume. Obviously returning a value is different from not returning a value.)
Restructuring your code to break out of a loop and reach the implicit return at the bottom of a function is not more efficient (but could easily be less efficient in some interpreted languages, especially if they aren't JITed.) e.g. if the interpreter does a jump within the function and then has to do another jump. (A good ahead-of-time compiler or JIT optimizer could see what was happening and make good machine code anyway.)
Some compilers / interpreters may handle a return by just jumping to a common block of cleanup (epilogue) that all return statements share. But tail-duplication is possible: when compiled to machine code, a function can have multiple copies of epilogue + ret instructions, reachable from different paths.
(JavaScript implementations do typically JIT functions to machine code; IDK about LUA. And of course they can inline functions. return statements in functions that get inlined can be just plain jumps, or could get optimized away entirely.)
I'm not exactly sure whether I correctly understood your question, but I'll try to answer it from my point of view.
The return statement in the end of a function declaration indicates to leave the function and return nothing (void). If you omit a return statement, nothing would happen after the actual function execution. Thus, I think the two functions you declared behave in a different way:
function a() {
// executes until the following statement and then breaks
return;
}
function b() {
// executes all statements and afterwards leaves the context where it was called
}
Regarding your question concerning inner blocks like condition checks or loops, I guess these statements could only be "optimized" by a parser somehow if they consist of static values like numbers or strings. As soon as any dynamic values like variables occur, it would be impossible to optimize anything or have an advantage from the inner result statement.
I hope you can get the point of my explanation.

Cleanest way to set up a chain of fallbacks?

So, I am geocoding addresses from the Google Places API. There are 38 Google address component types, and we have ~5 in-house address component types, so I need a system of mapping a number of Google types to our in-house types, with fallbacks.
For example:
var neighbourhood = googleResponse.neighborhood || googleResponse.sublocality_level_2 || googleResponse.sublocality_level_1
What is the best/cleanest/most efficient way to do this? Basically, I need to assign a var to some returned value, unless that returned value is undefined, and then move down the chain.
I think your approach is sound - using the short-circuiting ORs feels a lot cleaner than having some sort of branching statement to me. My two recommendations would be:
You should probably add some kind of hard-coded value (an empty string, perhaps? Depends on your use case) as a final fallback, so that if all of the options aren't found, you don't end up with the variable being set to something unexpected. I think being 100% explicit about all the possible things that could be returned is always a good practice.
I'd recommend pulling that logic out into a function, so that if you want to reuse it elsewhere it'll be more maintainable. Even if you don't think you'll need to use it again, it's still worth doing in case you change your mind later on - having to go through and replace every instance of a piece of code is incredibly tedious! It also makes your code a lot easier to test - you can pass in a hard-coded googleResponse and check that the output matches your expectations.
So my approach would probably look something like this:
function getNeighborhood(googleResponse) {
return googleResponse.neighborhood
|| googleResponse.sublocality_level_2
|| googleResponse.sublocality_level_1
|| "";
}
var neighborhood = getNeighborhood(googleResponse);
EDIT:
In response to your comment, there's a couple of options I can think of for values that have to be concatenated.
If it's just a matter of "everything or nothing", you could write this quite elegantly with a ternary expression:
function getStreet(googleResponse) {
return googleResponse.street_number && googleResponse.route
? googleResponse.street_number + googleResponse.route
: "";
}
However, if you start trying to nest these with fallbacks, it's going to get very unreadable very fast. At that point, you're better off just relying on a if/else if/else - it's a bit long winded, but it's comprehensible, and that's more important in my eyes.
function getStreet(googleResponse) {
if (googleResponse.street_number && googleResponse.route) {
return googleResponse.street_number + googleResponse.route;
}
else if (/* fallback */) {
return /* concat here */;
}
else {
// Make sure to always return a value, even if all of
// the other fallbacks fail!
return "";
}
}

Unless vs if in Javascript with use of exclamation point?

The code below attempts to print out "is even" for numbers divisible by 2.
Should it not be if (test) then() rather than: if (!test) then(), when condition tested is "n % 2". The code below seems to read "IF numbers are NOT divisible by 2, print out 'number is even' ", which does not seem logical.
More generally speaking, what are the advantages of writing an Unless function over using an If statement in specifying condition, when what we could do is simply write if (!condition)?
Any help is much appreciated.
function unless(test, then) {
if (!test) then();
}
function repeat(times, body) {
for (var i = 0; i < times; i++) body(i);
}
repeat(5, function(n) {
unless(n % 2, function() {
console.log(n, "is even");
});
// → 0 is even
// → 2 is even
// → 4 is even
The arguable advantage of this is that the code reads slightly more like English: "Unless n modulo 2 is nonzero, log to the console that n is even."
In my experience, the practical consequence of this is that most programmers will have to go double-check what unless() actually does before they feel comfortable with it. Because it's not a standard piece of Javascript, they have no way of knowing whether it uses ! or ==true or ===0 or some other ever-so-slightly different test, unless they go look at the implementation.
My favorite example of this principle is COBOL. That language tried very hard to resemble English, so that even non-programmers could use it...but in reality both programmers and non-programmers seem to hate working with it.
There are no advantages if the condition is provided inline as in this scenario. You can easily apply a transformation to negate it as appropriate in all cases (e.g. adding a ! in front), and taking unless out of the picture means there's one less thing the reader has to know about.
There could be an advantage if the condition was provided in the form of a callback, e.g.:
function test() { return true; }
function unless(test, then) { if (!test()) then(); }
unless(test, function() { console.log("test failed"); });
In this situation you could not directly pass the negation of test to a hypothetical function onlyIf that is complementary to unless, so having both onlyIf and unless can make the code more readable because it allows you to do this:
onlyIf(test, function() { console.log("test passed"); });
instead of this:
onlyIf(function() { return !test(); }, function() { console.log("test passed"); });
The above situation could be even worse if the callback is given arguments that need to be propagated into test.
I agree with Mahdi that this likely came about in reaction to an intentionally strange example of callbacks, but for the sake of completeness—plus a particular interest in negation—there is one more option:
if(test){}else{then}
This is shorter than unless() even after the arrival of arrow functions. It also keeps the metaphor of having a "free pass" on the expression. I think any further attempt to contend with the ! or ?: operator for grammatical reasons, realistically, would require the language to allow:
else(test){then}
Given this, I would still pick the former for flexibility, and for existing. :)

Assign variable in if condition statement, good practice or not? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I moved one years ago from classic OO languages such like Java to JavaScript. The following code is definitely not recommended (or even not correct) in Java:
if(dayNumber = getClickedDayNumber(dayInfo))
{
alert("day number found : " + dayNumber);
}
function getClickedDayNumber(dayInfo)
{
dayNumber = dayInfo.indexOf("fc-day");
if(dayNumber != -1) //substring found
{
//normally any calendar month consists of "40" days, so this will definitely pick up its day number.
return parseInt(dayInfo.substring(dayNumber+6, dayNumber+8));
}
return false;
}
Basically I just found out that I can assign a variable to a value in an if condition statement, and immediately check the assigned value as if it is boolean.
For a safer bet, I usually separate that into two lines of code, assign first then check the variable, but now that I found this, I am just wondering whether is it good practice or not in the eyes of experienced JavaScript developers?
I wouldn't recommend it. The problem is, it looks like a common error where you try to compare values, but use a single = instead of == or ===. For example, when you see this:
if (value = someFunction()) {
...
}
you don't know if that's what they meant to do, or if they intended to write this:
if (value == someFunction()) {
...
}
If you really want to do the assignment in place, I would recommend doing an explicit comparison as well:
if ((value = someFunction()) === <whatever truthy value you are expecting>) {
...
}
I see no proof that it is not good practice. Yes, it may look like a mistake but that is easily remedied by judicious commenting. Take for instance:
if (x = processorIntensiveFunction()) { // declaration inside if intended
alert(x);
}
Why should that function be allowed to run a 2nd time with:
alert(processorIntensiveFunction());
Because the first version LOOKS bad? I cannot agree with that logic.
I did it many times. To bypass the JavaScript warning, I add two parens:
if ((result = get_something())) { }
You should avoid it, if you really want to use it, write a comment above it saying what you are doing.
There is one case when you do it, with while-loops.
When reading files, you usualy do like this:
void readFile(String pathToFile) {
// Create a FileInputStream object
FileInputStream fileIn = null;
try {
// Create the FileInputStream
fileIn = new FileInputStream(pathToFile);
// Create a variable to store the current line's text in
String currentLine;
// While the file has lines left, read the next line,
// store it in the variable and do whatever is in the loop
while((currentLine = in.readLine()) != null) {
// Print out the current line in the console
// (you can do whatever you want with the line. this is just an example)
System.out.println(currentLine);
}
} catch(IOException e) {
// Handle exception
} finally {
try {
// Close the FileInputStream
fileIn.close();
} catch(IOException e) {
// Handle exception
}
}
}
Look at the while-loop at line 9. There, a new line is read and stored in a variable, and then the content of the loop is ran. I know this isn't an if-statement, but I guess a while loop can be included in your question as well.
The reason to this is that when using a FileInputStream, every time you call FileInputStream.readLine(), it reads the next line in the file, so if you would have called it from the loop with just fileIn.readLine() != null without assigning the variable, instead of calling (currentLine = fileIn.readLine()) != null, and then called it from inside of the loop too, you would only get every second line.
Hope you understand, and good luck!
If you were to refer to Martin Fowlers book Refactoring improving the design of existing code ! Then there are several cases where it would be good practice eg. long complex conditionals to use a function or method call to assert your case:
"Motivation
One of the most common areas of complexity in a program lies in complex conditional logic.
As you write code to test conditions and to do various things depending on various
conditions, you quickly end up with a pretty long method. Length of a method is in itself a factor that makes it harder to read, but conditions increase the difficulty. The problem
usually lies in the fact that the code, both in the condition checks and in the actions,
tells you what happens but can easily obscure why it happens.
As with any large block of code, you can make your intention clearer by decomposing it and
replacing chunks of code with a method call named after the intention of that block of code. > With conditions you can receive further benefit by doing this for the conditional part and
each of the alternatives. This way you highlight the condition and make it clearly what you > are branching on. You also highlight the reason for the branching."
And yes his answer is also valid for Java implementations. It does not assign the conditional function to a variable though in the examples.
I came here from golang, where it's common to see something like
if (err := doSomething(); err != nil) {
return nil, err
}
In which err is scoped to that if block only. As such, here's what I'm doing in es6, which seems pretty ugly, but doesn't make my rather strict eslint rules whinge, and achieves the same.
{
const err = doSomething()
if (err != null) {
return (null, err)
}
}
The extra braces define a new, uh, "lexical scope"? Which means I can use const, and err isn't available to the outer block.
You can do this in Java too. And no, it's not a good practice. :)
(And use the === in Javascript for typed equality. Read Crockford's The Good Parts book on JS.)
You can do assignments within if statements in Java as well. A good example would be reading something in and writing it out:
http://www.exampledepot.com/egs/java.io/CopyFile.html?l=new
The code:
// Copies src file to dst file.
// If the dst file does not exist, it is created
void copy(File src, File dst) throws IOException
{
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
It's not good practice. You soon will get confused about it. It looks similiar to a common error: misuse "=" and "==" operators.
You should break it into 2 lines of codes. It not only helps to make the code clearer, but also easy to refactor in the future. Imagine that you change the IF condition? You may accidently remove the line and your variable no longer get the value assigned to it.
you could do something like so:
if (value = /* sic */ some_function()){
use_value(value)
}

Where to perform argument validation in JavaScript?

Yeah, read properly. In the last time I saw different patterns of argument validation in JavaScript (functions) and wondered which of them would be best-practice. At first I'll show two example code snippets. The first shows an (in my words) "immediate" argument/condition validation and the second one a "delayed" validation. Each of them affect the appearance of following code in different ways. Up to now I always used the "immediate" validation. But slowly I am getting doubtful if it's reasonable to force the whole following code into such conditional blocks. Please tell me what you think and what might be the "best" pattern.
And what about the place where variables are declared? A few times I read, that ALL variables should be declared on to of the method, before they're actually used. Is this correct? Because I think that it is useless to declare variables before it is sure that they'll be actually used (maybe invalid arguments force the throw of an Exception), I moved the variable-declaration-part beyond the argument/condition validation part. Is this advisable?
Thanks!
First example:
if ( colorStops.constructor === Array
&& colorStops.length
&& colorStops.every(function(c) {
return c instanceof ColorStop
}))
{
var privateVar1 = "foo",
privateVar2 = "bar",
privateVar3 = "tutifrutti";
// here goes the code
}
else {
throw new TypeError("GradientCanvasFacade: cannot add Colors; " +
"invalid arguments received");
}
Second example:
if (cg instanceof ColorGradient) {
throw new TypeError("PresetManager: Cannot add preset; " +
"invalid arguments received");
}
var privateVar1 = "foo",
privateVar2 = "bar",
privateVar3 = "tutifrutti";
// here goes the code
// Here goes the code that get executed when no explicit
// return took place ==> all preconditions fulfilled
Since JavaScript variables are scoped to the declaring function and not to the block as most other languages, declaring variables at the beginning of the function makes alot of sense.
function someFunc()
{
if (1==1)
{
var x = 1;
}
else
{
var x = 2;
}
return x
}
Now imagine a function a lot more complex, to me atleast, declaring x at the beginning makes alot of sense. For variables generally bound to a block (like iterator variables or collections) I still declare them in the block though.
I would definitely go for your second example not because it fails earlier, because really it doesn't, but because it's easier to remove and add validations this way without breaking a complicated if structure.
I'd go with the second, simply because it's easier to read. Also, with the first, if your function is very long, someone looking at the bottom, will wonder what that } is for, and have to hop up to the top to see.
Also the scoping of variables is very clear, even for someone who forgets that javascript has weird scoping rules.
Also, as mentioned by Martijn, the second method makes it a lot easier to check for various errors, ie each can have their own if statement and so on.
if (some condition) {
if (some other condition based in the first) {
if (another condition based in 1st and 2nd) {
do_job();
} else?
} else?
} else?
Where to put the else block? After every if or after the last?
It seems absolutely more readable the second choise

Categories