javascriptreactjsfbjs

What purpose does makeEmptyFunction serve in fbjs?


I was looking through the React source and stumbled across a requirement with var emptyFunction = require('fbjs/lib/emptyFunction');.

I looked at this function and was confused by what it does.

Here is the function

function makeEmptyFunction<T>(arg: T): (...args: Array<any>) => T {
  return function() {
    return arg;
  };
}

const emptyFunction: (...args: Array<any>) => void = function() {};

In the comments, they give the following explanation which I was confused by:

This function accepts and discards inputs; it has no side effects. This is primarily useful idiomatically for overridable function endpoints which always need to be callable, since JS lacks a null-call idiom ala Cocoa

I have never come across null call idiom and was hoping someone could clarify what this means and explain the purpose of this function in less technical language.

Hopefully this question will not get looked down on because it isn't exactly code related. Maybe it belongs somewhere else, if so I'm sorry.


Solution

  • When programming in JavaScript, we can take a function as a parameter to a certain operation. As an example, a function may have a callback which is invoked after some kind of event.

    function doIt(callback) {
      // some work
      callback();
      // more work
    }
    

    Now if this callback is an optional parameter and it's not provided, we will get Uncaught TypeError: callback is not a function error because callback is undefined. There are two solutions to this issue. The obvious one is checking the callback with an if statement. Another option is set an empty function as the default value of callback if it's not assigned. This approach is very useful and shines if we have multiple places which invoke the callback function. So we don't need to check it for undefined every time before calling it.

    function doIt(callback) {
      callback = callback || function(){};
      // some work
      callback();
      // more work
    }
    

    Likewise, there are lots of use cases where we can have overridable functions variables. It's a common pattern to set these type of variables to empty function as the default value so that we can call them without worrying about whether those are assigned/overridden or not.

    Also, in some special cases, it's useful to have functions which do nothing but return a particular value. makeEmptyFunction is used for creating such functions. Basically, it returns a function which does nothing but returns what ever the parameter pass to it.

    emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
    

    As you can see in the file, above code generate an empty function which returns false value.

    "null call idiom" is something we find in Objective-C/Cocoa programming. It basically allows you to call a method of an uninitialized object (null pointer) without giving any errors like in most of the other languages. I think that's what the author have tried to explain in the comment.

    Since JavaScript doesn't have such language feature, we explicitly achieve it using empty functions. Some people call it no-op or noop and you can find similar helpers in other popular JavaScript libraries such as JQuery and AngularJS also.