Where to perform argument validation in JavaScript? - 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

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.

Is there a way to reuse the if(...) condition's value in the underlying scope?

Why
I'm a sucker for compact code and new language features. Therefore, I'm trying to find a way to reuse the value of the condition statement which opened the current scope without saving this beforehand as a variable in the parent scope, where it has no further use.
This would make my code more compact, yet easier to read, which is a pretty subjective feat. There probably are multiple of approaches to this, so all kinds of solutions are welcome (preferrably ES8, this is not for production use/professional environments).
Clarification:
The following function is cpu-intensive
fetchData() // returns [object Object] or false on error
It can also be an input stream whose output will differ upon every function call, or a key-value pair lookup which has to happen thousands of times in a short period but can only happen synchronously/blocking.
My current approach:
I have to type data 3 times and it pollutes the global scope. Also, while debugging with breakpoints, the variable is not found in the smallest possible scope.
let data = fetchData()
if (data)
useData(data)
else
error()
Not a good solution:
The data variable still occurs 3 times, pollutes the parent scope and you don't know what it means yet upon declaration. Single equation (=) sign can be interpreted wrongly by the reader OR corrected by someone else by mistake.
let data
if (data = fetchData())
useData(data)
The lazy way:
if (fetchData())
use(fetchData())
What i wish for:
The 'let' avoids interpreting it as an == conditional statement:
if (let data = fetchData()) { // data is declared in the child scope
parseData(data)
} else {
console.error('meh')
}
Result: SyntaxError: Unexpected identifier
or
if (fetchData()) {
parseData(fi)
}
or
// some kind of symbol, i know this is xor, but it seemed appropriate
if (long.object.key.value().chain.data)
return JSON.parse(^)
or
if (fetchData()) {
parseData(condition.value) // or .pop() or just 'condition'
}
I just feel like it's an information overload when looking back at my current approach, even if it has its advantages. I believe this can improve readability in situations where code is really dense or where function/variable names are so obvious they almost form a sentence.
Here is a way to do it without any declared variable:
[fetchData()].filter(Boolean).map(useData);
This is just for fun, I would not advise to actually use it, as it is neither efficient, nor very clear code.
NB: If you also need the meh output... then extend to:
[fetchData()].filter(Boolean).map(useData).length || console.log('meh');
No, there is no such syntax feature. The way to go is either a block scope
{
const data = fetchData()
if (data)
useData(data)
else
error()
}
or an IIFE
(function(data) {
if (data)
useData(data)
else
error()
}(fetchData()));
which you can of course also make into a reusable function:
function If(predicate, then, other) {
return function(value) {
if (predicate) then(value) else other(value)
};
}
If(Boolean, useData, error)(fetchData());

Can value of a JavaScript variable be changed twice in the same function?

Not sure if this is considered best practice or if you should even do this but I have a small block of Javascript and I want to know if you can declare a variable, display that variable and then reassign it and display it again? Syntactically this seems correct but I would assume that this is not best practice and should be avoided?
Note: I did not write this block I just want to know if it's ok or if I should change it and use 2 variables code below:
var u1 = 'something';
if (u1.indexOf('Accept') > 0)
{
var URL = 'some URL';
document.writeln(URL);
URL = 'another URL';
document.writeln(URL);
}
Thanks in advance.
EDIT:Thanks for the answers, thought it was a bit daft. :/
Yes you can
You can change variable's value as many times as you need to. Variables are quite often reused so we save memory resources. Not in the way you've used them (because that's an example that would be better off providing constant strings directly when calling functions) but think of an everyday example where we don't even think of multiple variable value assignments. A for loop:
for (var i = 0; i < 100; i++)
{
...
}
In this loop variable i gets assigned a new value 101 times. This is a rather obvious example, where we don't think of this at all, but other than that, we could have a set of loops and reuse the same variable more explicitly and assign it a value lots of times like:
var counter = 0;
for(var item = GetLinkedListFirstItem(); item != null; item = item.Next)
{
counter++;
}
// other code...
counter = 0;
while (counter < 10 || someOtherCondition)
{
// do something else
}
This may be a much better example of explicit variable reusability where its value gets changed lots of times and for different purposes.
Variable naming
Variable reuse is sometimes unwanted/undesired. And that's when we have a meaningful variable name like isUserLoggedIn. It's hard to reuse such variable for other purposes because it would make code unmaintainable.
Variables that are usually reused may hence be iterators (ie. i) or generally named variables without too much meaning. Or variables with more universal name (ie. finished) which can be reused in different contexts that can be associated with such variable name.
Asynchronous code
There are certain situations where you may have problems even though looking at code may seem perfectly fine. And that's when you use async functions which is frequently the case when using Ajax calls or time-deferred calls (ie. setTimeout). Consider the following code:
var loaded = false;
$.ajax({
url: "...",
type: "POST",
success: function(){
loaded = true;
}
});
if (loaded === true)
{
// do something important
}
// ok loaded not used any more, so we can reuse it
// we can easily change its type from number to string or anything else
loaded = "Peter loaded his gun";
This code has a bug, because important code won't be executed. Ever! This is quite a frequent misconception by unsavvy developers not understanding asynchronism.
Hint: When code issues an Ajax call it doesn't wait for a response but rather continues execution and executes if statement. Even though Ajax call would respond in 0time ticks, success function wouldn't execute until this currently running code wouldn't finish execution. That's how Javascript works. Queued code execution. In the end when Ajax async code would execute it would eventually overwrite the string that was stored in the variable.
Why not? Of course, it's normal to change variable value as much times as you want. That's actually reason why it's called "variable", not "constant" :)
I'd say it's perfectly fine to do so.
However, keep in mind that it can cause problems with asynchronous code. Take the following example for instance, where async accepts a callback that runs some time later:
var a = 123;
async(function() {
alert(a); // alerts 456, because `a` was set to 456
// *before* this callback was run.
// Because there is only one `a`, that variable
// has been overridden
});
a = 456;
async(function() {
alert(a); // alerts 456
});
Yes it is possible, and in this case there is no point in creating a new variable. However, if you have a lot of code reassigning a variable later could definitely be confusing especially if at first it's an object then later it is a string.
Variables can be reassigned in JavaScript. Whether they should or not is a question of style and context.
I normally prefer to re-use variables rather than create new ones

Shortest way of creating a "new function" alias in javascript

What's the shortest way (characters) of creating a "new function" alias.
Basically this is for code golf and minifying code beyond reason.
So when you usually would write:
a=function(a,b,c){return a+b+c;}
You could write something like (also let's abstract return keyword as well with global variable R):
a=$("a,b,c","R=a+b+c")
a=$(a,b,c){R=a+b+c}
(Not sure if the second one is possible.)
For the first example the best I've come up with is:
$=function(a,b){return new Function(a,"R=0;"+b+";return R")}
Both the sizes (usage, declaration) matter but usage size is more important.
I don't think new Function() is of viable use for most functions even without performance concerns because unlike function() {} no closure is created. The compiled function will only have access to its own local scope and the global object. Think about that for a second. Javascript without closures is like Java without classes or C without pointers. Clearly everything would break.
Anyways, if you only intend to use this alias for short lambada like expressions that don't need clousers, one obvious way to make things even more terse is to leave off the parameters deceleration. Simply assume that a = arguments[0]; b = arguments[1]; etc...
$=function(b){return new Function('a,b,c,d,e,f,g,h,i,j', b);};
Another way would be to automatically return the value of the last expression, instead of needing it to be explicitly declared
$=function(body) {
return function(a,b,c,d,e,f,g,h,i,j) { return eval(body); };
};
Horrifying isn't it? This works because eval()...well it returns the value of the last evaluated expression. No return needed. Of course this method is an even bigger hit to performance, as the code in body is reevaluated each time the function is called, while with new Function the code is (or should be) only compiled once.
Anyways performance be dammed, with the previous method your function declaration is down to this
var myeyes = $('a+b+c');
alert(myeyes(1,2,3)); //6
Purdy huh? Still, I think it would look better like this
'a+b+c'
Looks like a string yes? Well...it is a sting, but in the hands of the right function, it could be evaluated as if it were a full on function literal
//Lets just assume that IE does not exist mmkay?
var funcs = ['map', 'filter', 'every', 'some'];
for (var i=0; i<funcs.length; i++) {
(function() {
//Store original function
var name = funcs[i]
var _super = Array.prototype[name];
Array.prototype[name] = function() {
//$ !== jQuery
if (typeof arguments[0] == 'string') arguments[0] = $(arguments[0]);
return _super.apply(this, arguments);
};
}());
}
Now you can write
[1,2,3,4,5].map('a*a');
instead of
[1,2,3,4,5].map(function(a){return a*a;});
which is even better than Firefox's Expression Closure
[1,2,3,4,5].map(function(a) a*a);
Try it out here: http://jsbin.com/iyogu3/edit
If only we could actually write function expressions like this without calling upon the eval monster. Really, one of my main gripes with Javascript syntax is the requirement to spam function(){} throughout your code. Some kind of shorthand function literal syntax (not the aforementioned half-assed expression closure) that was interpreted the same as a regular verbose function literal would go a long way to making my code look a little less ridiculous. And it might help minifying a tiny bit as well.
For simple expressions, you could use:
function L(a,x){return new Function(a,'return '+x)}
Usage:
n=L('a,b,c','a+b+c');
You might get milage out of something silly like:
eval("t=Fa+b};t(1,2)".replace("F", "function(a,b){return "))
Here's a variant that has a larger overhead but saves one character per function definition.
"#" will be replaced with "return ".
$=function(a,b){return new Function(a,b.replace(/#/g,"return "))}
a=$("a,b,c","#a+b+c")
Your code:
a=function(a,b,c){return a+b+c;}
Shortened code:
a=(a,b,c)=>a+b+c
The shortest function declaration possible in js is 4 characters
Example: _=>1

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)
}

Categories