2

I'm writing some code that needs to deal with many potential JavaScript values including so-called non-values . I'm realizing it would be very helpful to know if there are some general rules about which native JavaScript functions can return null and which can return undefined. Thus this question.

Of course, any variable can be assigned null or undefined so I'm not talking about custom code including code from libraries. I'm only referring to native JavaScript functions (including in ES6/ES2015). Also, when I refer to "functions" I mean that in a very generic sense in that I'm referring to

  • global functions, e.g. parseFloat("99.99")
  • methods of built-in objects, e.g. Math.floor(99.99)
  • prototype methods, e.g. '$99.99'.match('$')
  • prototype properties, e.g. '$99.99'.length
  • operators (e.g. arithmetic, bitwise, etc.), e.g. 99.99 % 10

The following are some examples of the kind of rules I might hope for. I don't claim that any of them are correct or not. I'm just showing what I mean by categories:

  • All regex-matching functions (e.g. match, exec, test) can return null but never return undefined. (I don't think that's true, as it seems that test never returns null, but I'm not sure.)

  • While arithmetic operators might return NaN, they will never return null or undefined. (Is that true?)

  • No function from which you would normally expect a boolean will ever return null or undefined. (Is that true?)

  • Any return value that means "the empty set" (e.g. "no regex matches have been found", "no document elements with that id have been found") will always manifest itself as null. (Is that true?)

I'm particularly interested in edge cases, including functions used improperly, e.g. with a non-sensical parameter. For example, String.prototype.match can return null (e.g. 'abc'.match(Object)) but String.prototype.includes might never return null (e.g. 'abc'.includes(Object) returns false, not null).

If someone could add the new tag "undefined" to this question, that would be helpful. I don't have enough reputation points on 'Software Engineering' to do that.

  • 2
    “it can be difficult to intelligently guess what particular functions will return”: the thing is, you need to know what a function returns when you use it. And when you use it, you'll check MDN or simply call the function with different parameters. Also, I'm not sure if “make a list of...”-type questions are on-topic here. – Arseni Mourzenko Nov 10 '16 at 2:57
  • @ArseniMourzenko, one can be concerned about null or undefined values without knowing what particular functions are causing them, e.g. inside anonymous callbacks. In such cases I will never know when I will use a particular function, so I can't ever look it up. My use case that inspired my question was coding a "maybe" monad that would need to deal with null or undefined coming from any source, and I was just interested in creating a few different demo functions that would do so. Regarding "list of..." questions, if you know where I could migrate this to (StackOverflow?) I'd be happy. – Andrew Willems Nov 10 '16 at 3:51
  • 1
    Since you're asking for a list of functions, anonymous callbacks won't be there anyway, since they are anonymous. About the off-topic aspect, I'm not sure, so I asked a question on Meta. – Arseni Mourzenko Nov 10 '16 at 11:46
  • Regarding anonymous callbacks: Imagine I'm writing the following code: function myCoolLibraryUtility(someFunc) { return someFunc(myConstant);}. I now possibly need to deal with null or undefined return values from any function because the function itself will be provided not by me, the library creator, but by any library user. – Andrew Willems Nov 10 '16 at 13:03
  • I hear your concerns about requesting a comprehensive list. Thus, I've edited my question to simply ask for any general rules, if they exist. – Andrew Willems Nov 10 '16 at 13:23
1

You can eventually do it by parsing the ECMAScript Language Specification which conviniently provides the implementation of the native methods.

For instance, Object.defineProperty(O, P, Attributes) is documented like this:

  1. If Type(O) is not Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? ToPropertyDescriptor(Attributes).
  4. Perform ? DefinePropertyOrThrow(O, key, desc).
  5. Return O.

Here, simply by parsing the list, you can determine that:

  • The method actually returns something, because one of the elements from the list matches the Return .*\. pattern.

  • The method returns the parameter O, because O is among the arguments of the method.

Similarly, Array.prototype.find very conviniently tells you that sometimes, the method:

  1. Return[s] undefined.

The difficulty is that even this simplest example isn't easy to perform programmatcially. I suppose that while ECMAScript is very consistent in its descriptions of the methods, the high number of possible forms of those methods make any parsing of the documentation rather complex. For instance, Array.prototype.join returns R, but R is not an argument: instead, it is a value which is assigned through the statements such as:

  1. If element0 is undefined or null, let R be the empty String; otherwise, let R be ? ToString(element0).

Unless there is an actual BNF grammar that was used to write the spec, parsing such statements would be difficult to impossible.

The good side, however, is that if you achieve to create such parser, it will include the “edge cases, including functions used improperly” you were talking about.

My use case that inspired my question was coding a "maybe" monad that would need to deal with null or undefined coming from any source, and I was just interested in creating a few different demo functions that would do so.

In my humble opinion, creating the list of all JavaScript methods just to have “a few different demo functions” is an overkill. Why not limiting yourself by one or several methods and to use them as a demo?

Still using the spec, an example of a method which returns undefined is Array.prototype.find already listed above; for null, an example could be Date.prototype.toJSON.

  • Interesting idea. I did a quick "manual parse" of the spec, searching for "return null" and "return undefined". It was surprising to me how seldom null is returned from anything, with one of the few examples being the regexp-related functions exec and match that I listed in my question. Undefined gets returned more often. Using a related strategy I googled "null site:developer.mozilla.org". Get things like document.getElementById using a non-existent id, i.e. returning an empty set. – Andrew Willems Nov 10 '16 at 13:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.