What is the JavaScript convention for no operation?
JavascriptFunctionJavascript Problem Overview
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
or0
?
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;
Javascript Solutions
Solution 1 - Javascript
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.
Solution 2 - Javascript
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): [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
()=>{}
vs. Function.Prototype
()=>{}
is 87% faster thanFunction.prototype
in Chrome 67.()=>{}
is 25% faster thanFunction.prototype
in Firefox 60.()=>{}
is 85% faster thanFunction.prototype
in Edge (6/15/2018).()=>{}
is 65% less code thanFunction.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!`)
Solution 3 - Javascript
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.
Solution 4 - Javascript
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.
Solution 5 - Javascript
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.
Solution 6 - Javascript
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