I'm using:
MyTestFunction() && ExecuteMe();
for quick and easy conditional execution. I'd like to improve the code readability more in some places by creating:
Single line guard statments I.E:
MyTestFunction() && return;
//prevent execution of function early, but this isn't possible
Single line variable setters:
MyTestFunction() && myVar = 5;
(I realise I can do myVar = MyTestFunction() || 5; but that's not what I want)
Anyone see a nice way around this?
This works for me:
var num;
TestFunc() && (num = 5);
While I understand the programmers innate desire to do more things in less lines of code I think this violates some good programming principles about clarity in your code. Terse code saves space, but makes maintenance harder for the next programmer who looks at your code (and you should always assume there will be a "next programmer").
MyTestFunction() && (myVar = 5); // note the parens
// has the same effect as
if (MyTestFunction()) myVar = 5;
But I think the latter is much more readable and therefore easier to maintain.
I believe you are wanting to use a ternary statement
good thread here:
Operator precedence with Javascript Ternary operator
Related
I'm studying w3schools regarding semicolon placement (under the heading: "Statement Rules") and they said "Always end a simple statement with a semicolon." And: "Do not end a complex statement with a semicolon." They did not define what the difference between a simple and complex statement is and a thorough online search did not provide an answer either. So I am still confused with JavaScript semicolon placements. I would appreciate any help.
A complex statement is a sequence of ('simple') statements inside {}.
So you'd write (simple statement):
a = 3;
and (complex statement, in many languages called a compound statement, in JavaScript called a BLOCK)
{
a = 3;
b = 4;
}
but not
{
a = 3;
b = 4;
};
A simple statement in JavaScript is a single line of code that performs a specific task and does not require any additional statements to complete its execution. Example: x = 10.
A complex statement, also known as a compound statement, is a group of simple statements that are executed together as a single unit and controlled by a compound statement like if-else, for, while loop, etc. Example:
if (x > 10) {
x = 0;
y = 1;
}
Complex statement refers to blocks like in if, for, while etc.
if(condition){
} //no semicolon
Simple statement:
var x = 2;
In some cases, JavaScript allows you to omit the semicolon at the end of a statement. In other cases, it has to be there, or the next line will be treated as part of the same statement. The rules for when it can be safely omitted are somewhat complex and error-prone.
i recommend you check this Link
Looking through some JS code I have found something like this:
var a, b;
if (
(a = someFunction1(), b = someFunction2() )
){
...
}
I never found anything like this previously and I do not understand the reason for doing something like this. Therefore I am curious: is the person who has done this out of his mind or am I just not capable to understand his idea.
When I try to check what construct like (expression1, expression2) does, I see that it always returns the value of the second expression:
(5, 6) // 6
('strange', 'things') // 'things'
(4, undefined) // undefined
So if I would be the one writing this code, I would do something like this:
var a = someFunction1(),
b = someFunction2();
if (b){ ... }
Am I correct in my reasoning?
When I try to check what construct like (expression1, expression2) does, I see that it always returns the value of the second expression
Yes. Even without trying out, this is what the comma operator does.
Am I correct in my reasoning?
Yes. Your code does exactly the same thing, but is more readable.
You are correct, that is essentially if(b). The readability of the first version is terrible and does not save on space so it would make no sense for it to be minified like that.
Assigning variables inside of conditional statements is bad practice.
What is the JavaScript convention for no operation? Like a Python pass command.
One option is simply an empty function: function() {}
jQuery offers $.noop(), which simply calls the empty function above.
Is it acceptable to simply enter a value of false or 0?
In context... all of these work without throwing an error in Chrome:
var a = 2;
(a === 1) ? alert(1) : function() {};
(a === 1) ? alert(1) : $.noop();
(a === 1) ? alert(1) : false;
(a === 1) ? alert(1) : 0;
EDIT: A lot of people responded with, "don't do this! Change the code structure!" This reminds me of a post where someone asked how to sniff the browser. He received a barrage of posts saying, "DON'T DO THAT! IT'S EVIL," but nobody told him how to sniff the browser. This is not a code review. Imagine that you are dealing with legacy code that can't be changed, and without some function passed in, it will toss an error. Or, simply, that's the way the customer wants it, and they're paying me. So, respectfully, please answer the question: What is the best way to specify a "no operation" function in JavaScript?
EDIT2: How about one of these?
true;
false;
0;
1;
null;
To answer the original question, the most elegant and neat implementation of a noop function in pure Javascript (as is also discussed here) is Function.prototype. This is because:
Function.prototype is a function:
typeof Function.prototype === "function" // returns true
It can be invoked as a function and essentially does nothing as shown here:
setTimeout(function() {
console.log('Start: ', Date.now());
Function.prototype();
console.log('End : ', Date.now());
}, 1000);
Although this is a "true noop" since most browsers seem to do nothing to execute the noop defined this way (and hence save CPU cycles), there might be some performance issues associated with this (as is also mentioned by others in comments or in other answers).
However, that being said, you can easily define your own noop function and, infact, many libraries and frameworks also provide noop functions. Below are some examples:
var noop = function () {}; // Define your own noop in ES3 or ES5
const noop = () => {}; // Define in ES6 as Lambda (arrow function)
setTimeout(noop, 10000); // Using the predefined noop
setTimeout(function () {} , 10000); // Using directly in ES3 or ES5
setTimeout(() => {} , 10000); // Using directly in ES6 as Lambda (arrow function)
setTimeout(angular.noop, 10000); // Using with AngularJS 1.x
setTimeout(jQuery.noop, 10000); // Using with jQuery
Here is an alphabetical list of various implementations of noop functions (or related discussions or google searches):
AngularJS 1.x, Angular 2+ (Does not seem to have a native
implementation - use your own as shown above), Ember, jQuery, Lodash, NodeJS, Ramda, React (Does not seem to have a native implementation - use your own as shown above), RxJS,
Underscore
BOTTOM LINE: Although Function.prototype is an elegant way of expressing a noop in Javascript, however, there might be some performance issues related to its use. So, you can define and use your own (as shown above) or use one defined by the library/framework that you might be using in your code.
The most concise and performant noop is an empty arrow function: ()=>{}.
Arrow functions work natively in all browsers except IE (there is a babel transform if you must):
()=>{} vs. Function.Prototype
()=>{} is 87% faster than Function.prototype in Chrome 67.
()=>{} is 25% faster than Function.prototype in Firefox 60.
()=>{} is 85% faster than Function.prototype in Edge (6/15/2018).
()=>{} is 65% less code than Function.prototype.
The test below heats up using the arrow function to give bias to Function.prototype, yet the arrow function is the clear winner:
const noop = ()=>{};
const noopProto = Function.prototype;
function test (_noop, iterations) {
const before = performance.now();
for(let i = 0; i < iterations; i++) _noop();
const after = performance.now();
const elapsed = after - before;
console.info(`${elapsed.toFixed(4)}MS\t${_noop.toString().replace('\n', '')}\tISNOOP? ${_noop() === undefined}`);
return elapsed;
}
const iterations = 10000000
console.info(`noop time for ${iterations.toLocaleString()} iterations`)
const timings = {
noop: test(noop, iterations),
noopProto: test(noopProto, iterations)
}
const percentFaster = ((timings.noopProto - timings.noop)/timings.noopProto).toLocaleString("en-us", { style: "percent" });
console.info(`()=>{} is ${percentFaster} faster than Function.prototype in the current browser!`)
whatever you tend to achieve here is wrong. Ternary expressions shall not be used as a full statement, only in expression, so the answer to your question is:
none of your suggestions, instead do:
var a = 2;
if (a === 1)
alert(1)
// else do nothing!
then the code is easily understandable, readable and as much efficient as it can get.
Why make it more difficult, when it can be simple?
edit:
So then, does a "no-operation" command basically indicate an inferior code structure?
You're missing my point. All the above is about the ternary expression x ? y : z.
But, a no operation command does not makes sense in higher level languages such as Javascript.
It is usually used, in lower level languages such as assembly or C, as a way to make the processor do nothing for one instruction for timing purposes.
In JS, whether you do 0;, null;, function () {}; or an empty statement, there are great chances that it will be ignored by the interpretor when it is reading it, but before it gets interpreted, so in the end, you'll just make your program be loaded more slowly by a really tiny amount of time. Nota Bene: I'm assuming this, as I'm not involved in any widely used JS interpreter, and there are chances each interpreter has its own strategy.
In case you use something a bit more complicated, like $.noop() or var foo = function () {}; foo(), then the interpreter may do an unuseful function call that will end up spoiling a few bytes of your function stack, and a few cycles.
The only reason I see a function such as $.noop() would exist, would be to be able to still give a callback function to some event function that would throw an exception if it can't call that callback. But then, it's necessarily a function you need to give, and giving it the noop name is a good idea so you're telling your readers (and that may be you in 6 months) that you purposely give an empty function.
In the end, there's no such thing as "inferior" or "superior" code structure. You're either right or wrong in the way you use your tools.. Using a ternary for your example is like using a hammer when you want to screw. It'll work, but you're not sure you can hang something on that screw.
What could be considered either "inferior" or "superior" is the algorithm and ideas you put in your code. But that's another thing.
There is absolutely no problem or performance penalty of using Function.prototype over () => {}.
The main benefit of Function.prototype is having a singleton function rather than re-defining a new anonymous function each time. It's especially important to use a no-op like Function.prototype when defining default values and memoizing as it gives you a consistent object pointer which never changes.
The reason I'm recommending Function.prototype rather than Function is because of they're not the same:
Function() === Function()
// false
Function.prototype() === Function.prototype()
// true
Also, benchmarks from other answers are misleading. In fact, Function.prototype performs faster than () => {} depending on how you write and run the benchmark:
You can’t trust JS benchmarks << Specifically calling out benchmarks on this question.
Don't style your code from benchmarks; do whatever's maintainable and let the interpreter figure out how to optimize in the long run.
I think jQuery noop() is mostly intended to prevent code from crashing by providing a default function when the requested one is not available. For example, considering the following code sample, $.noop is chosen if fakeFunction is not defined, preventing the next call to fn from crashing:
var fn = fakeFunction || $.noop;
fn() // no crash
Then, noop() allows to save memory by avoiding to write the same empty function multiple times everywhere in your code. By the way, $.noop is a bit shorter than function(){} (6 bytes saved per token). So, there is no relationship between your code and the empty function pattern. Use null, false or 0 if you like, in your case there will be no side effect. Furthermore, it's worth noting that this code...
true/false ? alert('boo') : function(){};
... is completely useless since you'll never call the function, and this one...
true/false ? alert('boo') : $.noop();
... is even more useless since you call an empty function, which is exactly the same as...
true/false ? alert('boo') : undefined;
Let's replace the ternary expression with an if statement to see how much it's useless:
if (true/false) {
alert('boo');
} else {
$.noop(); // returns undefined which goes nowhere
}
You could simply write:
if (true/false) alert('boo');
Or even shorter:
true/false && alert('boo');
To finally answer your question, I guess a "conventional no operation" is the one which is never written.
I use:
(0); // nop
To test execution time of this run as:
console.time("mark");
(0); // nop
console.timeEnd("mark");
result: mark: 0.000ms
Using Boolean( 10 > 9) can be reduced it to simply ( 10 > 9) which returns true. Coming up with the idea to use a single operand I fully expected (0); would return false, but it simply returns the argument back as can be reviewed by performing this test at the console.
> var a = (0);
< undefined
> a
< 0
Need a succinct way of conditionally executing an expression, including function calls? (No noop necessary.)
true && expression // or `expression()`
Need a valid, callable expression with no side effects?
const noop = () => {}
if (true) noop()
Need a valid, non-callable expression with no side effects?
void 0;
false;
0;
In the following JavaScript statement:
var a = true;
a = a || b;
Will the a variable have an unneeded reasignment to it's own value?
Yes it will assign to a. This sort of thing probably wouldn't even be optimised in a compiled language.
It won't however waste time evaluating b however as it knows the result already. Something like this happens when a = a || b is run:
if a
a = a
else
a = b
EDIT:
To follow up what icktoofay said "it will not significantly impact performance.", it is simply setting a (boolean) variable which is one of the simplest operations that can occur. It will make little difference even if you're assigning to something more significant like a function or array as it will be assigning to a reference of the item, not creating it again.
Here is a performance comparison of doing nothing vs assigning to self (jsPerf link) thanks to #bfavaretto for setting it up.
a will be true when a or b is true. So yes, unless you insert some more code between those lines which can affect the value of a, the lower statement will always set a to true.
Yes - it won't be optimised away, because JavaScript doesn't optimise. Although the underlying parser implementation could conceivably optimise, I very much doubt it would in this case, and it would be very specific to the platform implementation.
While I was killing time looking up Javascript shorthand patterns, I came across an interesting way of expressing an if statement here. The following works:
var var1 = 5;
var var2 = 1;
var1 == 5 && var2++;
I think that's a totally cool (and shorter, cleaner) way of writing an if statement that only needs to do one operation. However, I ran into an issue with the following code as soon as I tried something else with it:
var var1 = 5;
var var2 = 1;
var1 == 5 && var2 = 2;
Instead of working like the first code snippet, my test throws an error:
Uncaught ReferenceError: Invalid left-hand side in assignment
Why doesn't this work, and why is the left-hand side of my statement being called out as incorrect as opposed to the right hand?
This doesn't work because the && operator has higher precedence than the = operator. In other words, your code is interpreted like this:
(var1 == 5 && var2) = 2;
If you manually put parentheses around the assignment, it will be interpreted correctly.
var1 == 5 && (var2 = 2);
Other people will reprimand you for writing code like this, saying that is a bad idea because it makes the intent of the code harder to read--which is true, especially for people unfamiliar with this idiom--but it is important to try it out and experiment with things like this to see for yourself what happens. You've already encountered one of the annoying things about this approach.
Anyway, in cases like this, I personally prefer to use single line if statements, like this
if(condition) statement;
Although I'm sure others will tell you that that's bad style because you have to manually add brackets when you need more statements, this hasn't really bit me and IMO it's cleaner than using three lines just for a simple condition, like you said.
Don't be alarmed that this doesn't work as you'd expect, in fact less than a month ago Brendan Eich (Creator of JavaScript) was sharing with us that this type of use is better known as an "abusage" of the language, since this logical operator isn't meant to execute code like this, but rather it's meant to determine the value of an expression.
"I also agree...that the && line is an abusage, allowed due to JS’s C heritage by way of Java, but frowned upon by most JS hackers; and that an if statement would be much better style..." http://brendaneich.com/2012/04/the-infernal-semicolon/
That being said, you can avoid the operator precedence issue by wrapping your statements:
(var1 == 5) && (var2 = 2)
because you are using an invalid operator on the right-hand side. its trying to read the entire statement as a single variable.
Is
var1 == 5 && var2++;
an cleaner or more understandable than this?
var2 += var1 === 5 ? 1 : 0;
In addition, the above expresses intent far more clearly than your code: the next guy who has to look at your code will see it and understand immediately what's going on, but looking at your code:
var1 == 5 && var2++
Is going to raise red flags in her head, because it looks like a bug or a some sort of typo — which means she's going to have to spend time trying to understand what you were actually trying to accomplish and whether or not the wonky code was intentional or not.
My first reaction, looking at
var1 == 5 && var2++ ;
Is that an assignment was intended:
var1 = 5 && var2++ ;
But the developer bounced the = key by accident, turning it into an orphaned expression (that happens to have side-effects).
Further, orphan expressions like that is likely to get flagged by any decent linter, for instance eslint's no-unused-expressions rule, as they indicate a probable bug.
Or
You could try using the ternary operator to make your code look concise.
When utilizing the '&&' operator fail or throw errors, I default back to the ternary operator.
Example:
let var1 = (conditional) ? "on true return" : "on false return";