Let's have a function call
function doSomethingAndInvokeCallback(callback){
// do something
callback();
}
I can check if given argument is function if(typeof callback == 'function')
How can I discover, if given callback function is function and isn't empty?
like
doSomethingAndInvokeCallback(function(){
//nothing here
})
There is no totally reliable way to know if a function is empty because there are multiple kinds of functions in JS, some implemented with JS and some implemented with native code and you can't know for sure whether the function passed in does anything or not. If you want to limit the passed in function to only very simple JS functions, you could use the mechanisms outlined by other answers here (examining the source of the function). But, I would not recommend doing that in anything but a tightly controlled situation because there are lots of legal javascript ways to break that.
I would suggest that you should change the contract of your function arguments and have the caller pass null or not pass anything (which will make the argument undefined) rather than an empty function. Then, it will be very clear whether they intend to have a function called or not. If they then pass an empty function instead of null or undefined, they are getting the behavior that the interface of the function specifies. The caller can choose the desired behavior and you can implement your function in a more failsafe manner.
Also, one of your main suppositions in your question is not quite right. You cannot safely use typeof x == "function" to determine if something is a function as that will not work reliably in some older versions of IE for some types of functions. If you want to learn how to detect if something is a function at all, you can learn from jQuery here (even if you're not using it). jQuery has a function it uses internally all the time called jQuery.isFunction() that returns a bool. It uses that mostly for testing arguments to see if a function was passed.
Internally, it calls:
Object.prototype.toString.call(o)
and then examines the result. If the result has "Function" in it, then test test parameter is a function.
So, using the same technique used in jQuery, you could build your own simple little isFunction routine like this:
function isFunction(test) {
return(Object.prototype.toString.call(test).indexOf("Function") > -1);
}
Of course, if you have jQuery available, you could just use it's own version:
jQuery.isFunction(o)
When there are questions with potential cross browser compatibility issues, I find it instructional to look at how one of the big libraries solves the issue, even if you aren't going to be using that library. You can be sure that the libraries have been vetted against many browsers so a technique they are using is safe. You sometimes have to unwrap all their own internal routines they may use to figure out what they're really doing (which was the case for this function), but you can save yourself a lot of legwork.
You can see a working test bed for this here: http://jsfiddle.net/jfriend00/PKcsM/
In modern browsers typeof fn === "function", but in older versions of IE, some functions give a typeof === "object" which is probably why jQuery uses this other method which does work in those older versions of IE.
It seems that you can define a function to retrieve the body of a function(1). I wrote a small (non-definitive) test of this:
http://jsfiddle.net/6qn5P/
Function.prototype.getBody =
function() {
// Get content between first { and last }
var m = this.toString().match(/\{([\s\S]*)\}/m)[1];
// Strip comments
return m.replace(/^\s*\/\/.*$/mg,'');
};
function foo() {
var a = 1, b = "bar";
alert(b + a);
return null;
}
console.log(foo.getBody());
console.log(foo.getBody().length);
One possibility is matching the .toString result against a regexp to get the function body, and then trim to check whether it has become an empty string:
var f = function foo() {
};
/^function [^(]*\(\)[ ]*{(.*)}$/.exec(
f.toString().replace(/\n/g, "")
)[1].trim() === ""; // true
That ugly regexp does take care of spaces aroung named functions as well as extraneous spaces before the name and the opening brace. Spaces like in foo () do seem to be removed, so there is no reason to check for those.
You might be able to get this from .toString():
var blank = function(){};
var f = function(){};
var f2 = function() { return 1; };
f.toString() == blank.toString(); // true
f2.toString() == blank.toString(); // false
but this is really prone to error:
var blank = function(){};
var f = function(){ }; // extra space!
f.toString() == blank.toString(); // false
You could munge the strings a bit to try to overcome this, but I suspect this is very browser-dependent. I wouldn't actually try to do this in a production environment if I were you. Even if you normalize the whitespace, it still won't catch other no-op lines, including comments, useless var statements, etc. To actually address these issues, you'd probably need a whole tokenizer system (or a crazy regex).
You can't do it for a host function, but for others, you can fairly reliably do
function isEmpty(f) {
return typeof f === "function" &&
/^function[^{]*[{]\s*[}]\s*$/.test(
Function.prototype.toString.call(f));
}
This isn't efficient, but major interpreters implement toString for functions in such a way that it works, though it will not work on some interpreters for some empty-ish functions
function () { /* nothing here */ }
function () { ; }
function () { return; }
In some implementation you can just do a toString() on the function and get it's content. Though it contains comments etcetera.
var foo = function(){ /* Comment */ };
alert(foo.toString());
Related
I am reading a very comprehensive javascript programming book. In the "functions" section of language basics I have come to the following:
"The return statement can also be used without specifying a return value. When used in this way, the function stops executing immediately and returns undefined as its value. This is typically used in functions that don’t return a value to stop function execution early, as in the following example, where the alert won’t be displayed:"
function sayHi(name, message) {
return;
alert(“Hello “ + name + “, “ + message); //never called
}
I am trying to understand why anyone would want to do this. Why write a function that returns "undefined"? I have tried googling, and searching SO, but have not had much luck though this may be because I am not phrasing my search correctly as I am learning js.
Can anyone give me a real-world example of where this might be useful so that I can understand?
Usually it's a conditional return. Something like
function calculateSomething(obj, condition) {
if (condition !=0 ) return;
obj.data = obj.data * 42;
}
in this case if some condition fails - function exits right away. Otherwise data in a passed object is modified.
The function you provide is useless...
However, not every function needs to return something. Sometimes a function does things "elsewhere" and the value that is returned is irrelevant.
The function may have side effects, such as altering the state of the page. Then, the caller may not expect any return value.
In my opinion, learned from masters so to speak, the idea here is to only temporarily disable the function. So if you have like an x amount of function calls to sayHi() like for example in a repeater or spread out over multiple files, the idea can be useful to simply return; without a value. Useful? Yes, to avoid commenting out chunks of code, but that's it.
Leaving this in a development environment, which initially will enter the www, you should not write it like this, and always make sure that: when a function has to return "something", then "something" always counts for value, no matter what the condition. With lowest value a boolean => return false;. This counts for every code block inside that function => for if else while ...
/* INCORRECT: it only returns something conditionally */
function do(something){
if (condition){
return false;
}
}
/* CORRECT: it returns value no matter what the condition */
function do(something){
if (!condition){
return true;
}
return false;
}
/* OPTIMIZED: a lot of ideas can be optimized, especially when returning booleans */
function do(something){
return !condition;
}
The rules only apply if you want to write proper code. Using tools like jslint, jshint or re-sharper helps a lot in understanding the basic principles of writing ecmascript valid code. Since not everyone is aware of these rules, all examples will yield the same result. In the sens of "it works, but it's not valid code".
Because A JS function is an object(has:Attributs+methods)
And , An object should have a value which can be undefined .
The proof is that
function sayHi(){}
Can be handled such as object even calling it :
var returnedValue=sayHi.call() ;
If sayHi does not return anything, returnedValue will be undefined
Example if you want to use classes I am sure about it you will use setter functions to give value for an instance attribute.
Like this:
function Something(val) {
this.value = val;
}
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;
I have a potentially strange question about this and jQuery plugins
As I understand it, the following is a very basic jQuery plugin:
$.fn.clickclone = function(param){
return this.click(function(){
param.apply(this);
});
};
(pretending that's a plugin that somehow extends click().)
So, if I pass a function as an argument, it does what it needs to do and properly accesses this as a DOM node. Easy.
That's all clear to me.
What's not clear is, is there any way I could pass a non-function argument to the plugin and have it properly access this from the arguments? ie, could I configure the plugin to do something like this:
$("#foo").pluginname(["foo", $(this).text() ]);
Such that for:
Bar
It would properly pass an array to the plugin, with the second item in the array returning the value Bar?
I'm doing this, basically, to provide syntactic sugar for my plugin, where you can pass an array as a shortcut (in addition to using a normal callback function as the main functionality). Except, doing that, I lose access to use of this. Hence my dilemma.
EDIT: This is evil, but, it seems like one work around is to pass the argument as a string and then eval it. Not a workable solution for me, but, it illustrates what I'd like to be able to do:
$.fn.clickclone = function(param){
return this.click(function(){
if(typeof param === "function"){
param.apply(this);
}
else if(typeof param[1] === "string"){
console.dir("This is evil: " + eval(param[1]));
}
});
};
There's no general way to do this without a function, since, in the purely mathematical sense, you are asking for a function of the input (that is, a function of this): something that depends on this in a certain way.
You could perhaps hack it with strings, like so, but you lose the flexibility of functions:
$.fn.alertMe = function (methodToAlert) {
alert(this[methodToAlert]());
};
// usage:
$("#foo").alertMe("text");
$("#foo").alertMe("width");
And if you find using a function acceptable but the this syntax confusing, you can simply do the following:
$.fn.alertMe = function (alertGetter) {
alert(alertGetter($(this));
};
// usage:
$("#foo").alertMe(function (x$) { return x$.text(); });
$("#foo").alertMe(function (x$) { return x$.width(); });
And for completeness I guess I should mention you could probably get away with an eval-based solution, looking something like $("#foo").alertMe("$(this).text()"), but eval is evil and I will neither write up nor condone such a solution. EDIT: oh, I see you have done so in an edit to your original post. Good job corrupting future generations ;)
I just read through this article on named function expressions and their incompatibilities with IE <= 8.
I'm curious about one statement in particular:
A common pattern in web development is to “fork” function definitions based on some kind of a feature test, allowing for the best performance.
An example taken from his page:
var contains = (function() {
var docEl = document.documentElement;
if (typeof docEl.compareDocumentPosition != 'undefined') {
return function(el, b) {
return (el.compareDocumentPosition(b) & 16) !== 0;
};
}
else if (typeof docEl.contains != 'undefined') {
return function(el, b) {
return el !== b && el.contains(b);
};
}
return function(el, b) {
if (el === b) return false;
while (el != b && (b = b.parentNode) != null);
return el === b;
};
})();
When I see this, my immediate reaction is that this would be terrible to maintain. Code written this way doesn't really lend itself to being easily understandable.
In this case, instead of conditionally defining a function within another function which is then called immediately after the outer function is declared, one could write a function of nested ifs. It would be longer, but in my opinion easier to understand (though I am coming from C/C++/Java).
I would prefer answers that include some test numbers or explanations on how these functions would differ at run time.
It is very efficient. Notice the (); at the very end. This executes and assigns the result of the outer function to contains immediately. It is much more efficient than executing the underlying logic every time that the function contains is used.
Instead of checking each time contains() is called that compareDocumentPosition exists, this is done once when the code first executes. The fact that compareDocumentPosition exists or doesn't exist won't change, so only checking it once is ideal.
Javascript: how much more efficient is forked function declaration?
Barring any magic optimization done with a JIT/run-time it "costs" the same to invoke any function. Functions are just objects that are often stored in variables (or properties).
How much more "efficient" the version that returns a specialized function-object is depends upon factors including (but not limited to):
the number of times the resultant function is executed (1x = no gain) and
the "cost" of the branch vs. other code (depends) and
the "cost" of creating said closure (very cheap)
For a cheap branch or a low number of execution counts the "efficiency" is diminished. If there is a specific use-case, then benchmark that and you will have "the answer".
When I see this, my immediate reaction is that this would be terrible to maintain. Code written this way doesn't really lend itself to being easily understandable.
This example doesn't necessarily do it justice, IMOHO and is messy for other reasons. I think that giving the anonymous outer function an explicit name -- this can be done even for function-expressions -- would help clarify the intent better, for instance. Write code to be clean first. Then run a performance analysis (benchmark) and fix as appropriate. Chance are the "slow parts" won't be what are initially expected.
Some of it "not being easy to understand" is just a lack of familiarity with this construct (not trying to imply anything negative here) -- on the other hand, every language I know of has features which are abused in cases where there are cleaner solutions.
In this case, instead of conditionally defining a function within another function which is then called immediately after the outer function is declared, one could write a function of nested ifs. It would be longer, but in my opinion easier to understand (though I am coming from C/C++/Java).
Again, the exact case is sort of messy, IMOHO. However, JavaScript is not C/C++/Java and functions-as-first-class-values and closures do not exist in C/C++/Java (this is a little white lie, closures can be emulate in Java and the newest C++ supports some form of closures AFAIK -- but I don't use C++).
This construct is thus not seen in those other languages because the other languages do not support it easily (or at all) -- it says nothing about the viability of the approach (in JavaScript or elsewhere) in general.
I would prefer answers that include some test numbers or explanations on how these functions would differ at run time.
See above.
Expanding upon the bold section at top:
A function is "just an object" that is "applied" (read: called) with the (...) operator.
function x () {
alert("hi")
}
x() // alerts
window.x() // alerts -- just a property (assumes global scope above)
a = {hello: x}
a.hello() // alerts (still property)
b = a.hello
b() // alerts (still just a value that can be invoked)
Happy coding.
The main advantage as mentioned is speed. Having a single function with nested ifs means the condition needs to be re-evaluated every time the function is called. However, we know that the results of the conditions will never change.
If you are concerned about readability, a similar effect can be achieved in a more readable way:
var contains = (function () {
var docEl = document.documentElement;
if (typeof docEl.compareDocumentPosition != 'undefined') {
return contains_version1;
} else if (typeof docEl.contains != 'undefined') {
return contains_version2;
} else {
return contains_version3;
}
function contains_version1() {
...
}
function contains_version2() {
...
}
function contains_version3() {
...
}
})();
Or:
(function () {
var docEl = document.documentElement;
var contains =
typeof docEl.compareDocumentPosition != 'undefined' ? contains_version1 :
typeof docEl.contains != 'undefined' ? contains_version2 :
contains_version3;
function contains_version1() {
...
}
function contains_version2() {
...
}
function contains_version3() {
...
}
})();
This is relatively strange construct if you are coming from pure C background, but should be easily to map to known concepts for C++/Java person. This particular sample is essentially implementation base class with abstract function with 3 derived classes implementing it differently for different browsers. Using "if" or "switch" for such case is not exactly the best approach in either C++ nor Java.
Likely set of such functions will be packaged into a "class" and in such case it will closely map to base class with virtual functions and multiple implementations for each browser...
I saw these 2 basic ways of namespacing in JavaScript.
Using object:
var Namespace = { };
Namespace.Class1 = function() { ... };
Using function:
function Namespace() { };
Namespace.Class1 = function() { ... };
How do they differ? Thank you.
As others have pointed out, a function is an object so the two forms can be interchangeable. As a side note, jQuery utilizes the function-as-namespace approach in order to support invocation and namespacing (in case you're wondering who else does that sort of thing or why).
However with the function-as-namespace approach, there are reserved properties that should not be touched or are otherwise immutable:
function Namespace(){}
Namespace.name = "foo"; // does nothing, "name" is immutable
Namespace.length = 3; // does nothing, "length" is immutable
Namespace.caller = "me"; // does nothing, "caller" is immutable
Namespace.call = "1-800-555-5555" // prob not a good idea, because...
// some user of your library tries to invoke the
// standard "call()" method available on functions...
Namespace.call(this, arg); // Boom, TypeError
These properties do not intersect with Object so the object-as-namespace approach will not have these behaviours.
The first one declares a simple object while the second one declares a function. In JavaScript, functions are also objects, so there is almost no difference between the two except that in the second example you can call Namespace() as a function.
Well, if all you're doing us using that "Namespace" thing as a way to "contain" other names, then those two approaches are pretty much exactly the same. A function instance is just an object, after all.
Now, generally one would use a function like that if the function itself were to be used as a constructor, or as a "focal point" for a library (as is the case with jQuery).
They don't. Functions are "first class objects". All this means is that conceptually and internally they are stored and used in the same ways. Casablanca's point of one difference you can call it as a function is a good one though. You can also test for whether or not the class was defined through a function with the typeof operator.
typeof {}
returns "object"
typeof (function())
returns "function"