162

I have a function which I have written which basically looks like this:

function getNextCard(searchTerms) {
  // Setup Some Variables

  // Do a bunch of logic to pick the next card based on termed passed through what I'll call here as 'searchTerms' all of this logic is omitted because it's not important for my question.
  // ...

  // If we find a next card to give, than give it
  if (nextCardFound)
    return nextCardFound;

  // Otherwise - I'm returning undefined
  return undefined;
}

Question: Would it be better to return "null" here?

I can pass whatever I want back - obviously... I just wasn't sure what is the best thing to use.

The code that calls this function knows how to deal with undefined (it actually won't ever really happen unless something goes horribly wrong)

The reason I'm asking this question is that I heard somewhere something that sounded like "Don't assign undefined to variables" or something - that it will make it harder to debug. So, the fact that I can see that null gets passed back tells me that the return is working - but basically function similar to undefined.


Documentation:

Mozilla Docs Didn't answer my question... google didn't either :\

This SO Question - was way too broad for what I'm trying to figure out here.

Community
  • 1
  • 1
Jeremy Iglehart
  • 4,281
  • 5
  • 25
  • 38
  • 1
    doesn't this [SO Question](http://stackoverflow.com/questions/801032/why-is-null-an-object-and-whats-the-difference-between-null-and-undefined) answer? – warkentien2 Jun 23 '16 at 00:59
  • 12
    In my opinion, return `null`. Leave `undefined` to JavaScript itself. However, there is no "better" so this is a matter of opinion. – Felix Kling Jun 23 '16 at 00:59
  • @warkentien2 Thanks, this was helpful - but I'm still unclear as to what the convention is here for returning from a getter function. – Jeremy Iglehart Jun 23 '16 at 01:08
  • 2
    I read `null` as "there is no appropriate value for what you're asking for" and `undefined` as "I can't work out what you're asking for". – Marty Jun 23 '16 at 01:12
  • @warkentien2 that question, and the one I linked in my answer, are related, but both seem to be asking *what* is the difference between them and not *when* to use one or the other as a return value. – chiliNUT Jun 23 '16 at 01:13
  • You could alternatively return `false`, or "search term not found", to notify caller of function which performs search for `searchTerm` that a search did occur, though no matches were found. – guest271314 Jun 23 '16 at 01:18
  • The question is incorrectly closed as opinion-based. There are good reasons explaining why undefined is preferred. See https://palantir.github.io/tslint/rules/no-null-keyword/ – Michael Freidgeim Jul 09 '23 at 08:32

10 Answers10

164

Undefined typically refers to something which has not yet been assigned a value (yet). Null refers to something which definitively has no value. In that case, I would recommend returning a null. Note that a function with no specified return value implicitly returns undefined.

From the ECMAScript2015 spec

4.3.10 undefined value

primitive value used when a variable has not been assigned a value

4.3.12 null value

primitive value that represents the intentional absence of any object value

http://www.ecma-international.org/ecma-262/6.0/#sec-terms-and-definitions-undefined-type

Further reading:

When is null or undefined used in JavaScript?

Community
  • 1
  • 1
chiliNUT
  • 18,989
  • 14
  • 66
  • 106
  • 2
    Yes, undefined is the value used when a variable has not been assigned a value. Why exactly does that imply you shouldn't return undefined in a function? – Oriol Jun 23 '16 at 01:22
  • 3
    @Oriol, in my mind, since a void function returns undefined, that is a reserved value for functions of that type, so that when handling the return value of a function, null tells me it decided to return null, whereas undefined tells me it either decided to return undefined, or it decided not to return anything, but I don't definitively know which. Further, if I am doing `var x=someFunc();`, I am intentionally assigning x a value, and would rather it not pass any tests which indicate it has not (or may have not) been assigned a value. Just imho – chiliNUT Jun 23 '16 at 01:29
  • This should be the accepted answer. This is how it was intended to be used in the spec – curv Mar 06 '20 at 12:14
  • `null` refers to the absence of any `object` value. As much as I like to use it because it's the same word from other languages, a number or a string should be undefined, not null, according to the spec (also that's why `typeof null === 'object'`) – Sergio Rosas Mar 24 '20 at 15:32
  • @SergioRosas can you link to the spec that says that undefined should be used for a number or a string? – chiliNUT Mar 24 '20 at 15:50
  • I'm not saying `undefined` should only be used for string number and non objects, or that you can't use it to say absence of `object` value, but just from those specs `null` seems to be reserved for absence of `object` value. In the end, how you use `undefined` or `null` depends on your code and how you define your interfaces – Sergio Rosas Mar 24 '20 at 16:35
  • 1
    I don't read it that way. I read it as: If you define a variable but don't initialize it, it will instead have an initial value of undefined. Null should be used by the programmer to intentionally indicate that a variable is empty. IMHO undefined should never be assigned to a variable by the programmer, leave it up to the js engine to use it. The term "object" value is misleading, since in JS even the primitives behave like objects for the most part due to autoboxing – chiliNUT Mar 24 '20 at 19:07
  • 2
    Yeah, that makes sense. To be fair, I don't mind using one over the other (although I'm more used to `null`) as long as you stick with one, but having 2 values to indicate absence of value (whatever the "type") is always confusing – Sergio Rosas Mar 26 '20 at 15:04
84

I will give you my personal opinionated way of choosing between the two.

My simple question is: could the value, given another input/state/context be defined to something?

If the answer is yes then use null else use undefined. More generally any function returning an object should return null when the intended object does not exist. Because it could exist given another input/state/context.

null represents the absence of value for a given input/state/context. It implicitly means that the concept of the value itself exist in the context of your application but may be absent. In your example the concept of a next card exists but the card itself may not exist. null should be used.

undefined implicitly represents the absence of meaning of that value in your application's context. For example, if I manipulate a user object with a given set of properties and I try to access the property pikatchu. The value of this property should be set to undefined because in my context it doesn't make any sense to have such a property.

KenBuckley
  • 573
  • 6
  • 13
ngryman
  • 7,112
  • 2
  • 26
  • 23
  • 4
    This rings so true to me. IMO pure functions should return `null`, while functions with side-effects should return `undefined`, when thinking like a functional programmer. – Jake Aug 11 '19 at 21:09
  • Aren't the default JS functions conflicting with this? When I use the find function, for example, it returns undefined when no value was found. But it could have returned something when I inputted something else, right? – juliushuck May 27 '22 at 14:22
49

I will argue there is no best way, and even standard functions sometimes choose one or the other.

For example:

  • [[Prototype]]

    Ordinary objects have a [[Prototype]] internal slot, which determines from which other object they inherit from. Of course, there must be a way to say that an object does not inherit from any other one. In this case, "there is no such object" is represented using null.

  • Object.getOwnPropertyDescriptor

    It is expected to return a property descriptor, that is, an object which describes a property (e.g. value, writability, enumerability and configurability). However, the property may not exist. In this case, "there is no such property" is represented using undefined.

  • document.getElementById

    It is expected to return the element with the given ID. However, there might be no element with that ID. In this case, "there is no such element" is represented using null.

So just choose whatever you prefer or think makes more sense for your specific case.

Oriol
  • 274,082
  • 63
  • 437
  • 513
  • 3
    after [reading this](http://ryanmorr.com/exploring-the-eternal-abyss-of-null-and-undefined/) I decided to suggest the `void 0` technique for future viewers of this answer. I also added some code to try and make your point more clear. Thank you for your answer! – Jeremy Iglehart Jun 23 '16 at 02:15
  • Great point here - another perfect example is [Array.prototype.find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). – jbyrd Jul 06 '22 at 19:24
4

Depends on what u need to do with the returned value.

typeof null returns an object. that object has a value of undefined

typeof undefined returns undefined

Dan
  • 774
  • 5
  • 11
  • Personally i usually use null. – Dan Jun 23 '16 at 01:02
  • 4
    *"that object has a value of undefined"* No it's not and it's not an object, it's Null. `typeof` doesn't necessarily return the true data type of a value, it has a map that maps data types to labels and returns the corresponding label. – Felix Kling Jun 23 '16 at 01:04
  • 1
    Don't trust `typeof`, despite its name it doesn't tell the type of a value. – Oriol Jun 23 '16 at 01:20
4

undefined is not something you should assign to. You might want to consider to return something else other than undefined. In your case, even if you don't return anything at all, the result will be undefined already. So, I'd suggest to go with null instead.

Consider this sample,

function getSomething() {
     // .. do something
     return undefined;
}

function doSomething() {
     // .. I'm not gonna return anything.
}

var a = getSomething();
var b = doSomething();

Above sample result in a === b, which is undefined. The difference is that you save 1 statement execution.

choz
  • 17,242
  • 4
  • 53
  • 73
  • @Oriol I mean, `undefined` does not have to be assigned. All declared variable without values are already `undefined`. – choz Jun 23 '16 at 01:22
  • @choz & @Oriol - as mentioned before by @chiliNUT "Note that a function with no specified return value implicitly returns undefined." - this is true because `(function(){ /* code */ })()` returns null in a console. – Jeremy Iglehart Jun 23 '16 at 01:25
  • 1
    @JeremyIglehart That code actually does not return anything. And else, it gives `undefined` on my chrome and firefox console. – choz Jun 23 '16 at 01:29
  • 1
    OK I didn't understand your point. Yes, if you don't return anything explicitly, undefined will be returned implicitly. But why does that matter? – Oriol Jun 23 '16 at 01:29
  • 1
    @Oriol, I think what @choz was trying to say (as a few other also mentioned on this question) that if I want to return `undefined` if something else doesn't return earlier - I don't need to because the function's default behavior if you don't return anything is to return undefined - they are just saying that this is not needed. Further... I like what you had to say about built-in getter functions returning null. Please post your answer to that effect and I will accept it. – Jeremy Iglehart Jun 23 '16 at 01:36
  • 1
    I still prefer to explicitly return `undefined` as it documents the intent of the code. Otherwise, when I see a function that doesn't return anything I have to ask myself if the dev who wrote it, just forgot to return something. – zett42 Sep 09 '19 at 14:20
4

I would argue that in this case, null should be returned.

If you consider the question from a theoretical computer science point of view then undefined is used to indicate non-termination/ non-computability (i.e. the placeholder for an undefined point x of a partial function f which is often written f(x) = ⊥).

getNextCard however seems to be able to compute the next card (if it exists) and also be able to compute if there is no next card. In other words, the function is total since it terminates for every input.

That being said, a special value signalling termination without meaningful result (i.e. "there's no card I can return for this input") is required and this for me is null not undefined.


NOTES:

You can see some support for this argument in some other typed languages as well where termination without meaningful result are expressed using an option type (sometimes also referred to as nullable type). An example for this is is Maybe in Haskell.

On the other hand, we of course do not know what undefined in JavaScript is really supposed to mean. So, the analogy to undefined is a bit tenous. Moreover, since we always want to work with total functions, this amounts to saying "never return undefined from a function". Which seems to be a bit strict, since it would limit the use of undefined to properties/ variables which have not been set.

In the end, my personal preference is never to return undefined where I can return null and I would also argue that this is the better coding convention (because among other things x !== null is shorter than typeof x !== 'undefined').

FK82
  • 4,907
  • 4
  • 29
  • 42
3

Here's an example where undefined makes more sense than null:

I use a wrapper function for JSON.parse that converts its exception to undefined:

// parses s as JSON if possible and returns undefined otherwise
// return undefined iff s is not a string or not parseable as JSON; undefined is not a valid JSON value https://stackoverflow.com/a/14946821/524504
function JSON_parse_or_undefined(s) {
    if ("string" !== typeof s) return undefined

    try {
        const p = JSON.parse(s)
        return p
    } catch (x){}

    return undefined
}

Note that null is valid in JSON while undefined is not.

masterxilo
  • 2,503
  • 1
  • 30
  • 35
  • I see what you're doing there - and I can't say you're wrong - because in a sense I think you could do this here and it would be fine. I have a different pattern that I use to do this operation that I like better because I do a "validation" step after. I feel like this is getting validation mixed with returning the value. Here is what I do: `let getStringOrJSON = value => { try { value = JSON.parse(value); } catch(e) { return value; } return value; };`. Now, I'm sure the two returns could be handled differently, and might not win the JS golf competition. It works. – Jeremy Iglehart Jan 25 '18 at 22:19
1

First answer is right. They have theoretically different meaning. However it's not always clear which to pick up.

I tend to use null in my development although I think that's completely subjective thing.

I use that mostly because:

  1. undefined variable might be overwritten in old browsers so returning it is a little bit more complicated. This same issue forces you to use typeof var === 'undefined' when getting function results. link

  2. Other languages tend to use null widely, a lot of them don't even have undefined (php for example). That gives me kind of consistency when quickly swapping between languages.

Community
  • 1
  • 1
Maciej Paprocki
  • 1,230
  • 20
  • 29
1

I think it is very debatable what to use. I prefer code that is semantically as accurate as possible, so I think undefined is appropriate in this case.

I think of null assignments as meaning "a variable set to nothing". This is as opposed to undefined meaning "this thing isn't there at all"

As a previous answer pointed out, returning undefined has issues, and it's completely up to you whether that bothers you. It wouldn't bother me.

  • 2
    But `document.getElementById('iDoNotExist')` returns `null`, even though the meaning is closer to "this thing isn't there at all". If standard methods do it, why not OP? – Oriol Jun 23 '16 at 01:24
  • @Oriol I actually like your reasoning the most. Please post an answer to this effect and I will accept it. ( I might even add a few edits if needed ) – Jeremy Iglehart Jun 23 '16 at 01:31
  • Yah @Oriol, this is why I actually enjoy debates, even on Q/A sites. It's really good to get counter examples. And you've provided a good one. – Ryan Laboucane Jun 23 '16 at 01:55
  • On the other hand, `array.find()` returns `undefined` if the array doesn't contain searched value. It's not consistent, I agree. – Ariod Dec 11 '21 at 23:24
0

All answers are correct. I'm adding my 2 cents.

Another important question to ask is:

What will the caller of your function do?

In most cases it wouldn't matter anyway. Js/Ts developers usually check something as !fnCall() instead of fnCall() === undefined.

But in some cases, ! doesn't do what we want. Like if the function returns int, someone might be tempted to do a fnCall() === undefined check since 0 is a valid response.

Vedant Agarwala
  • 18,146
  • 4
  • 66
  • 89