最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Handling the distinction between undefined- and null-parameters in JavaScript - Stack Overflow

programmeradmin2浏览0评论

I know very well that null and undefined are distinct in JavaScript. However, I can't seem to decide whether or not use that fact when my own functions are passed one of those as its argument.

Or, expressed in a different way, should myFoo(undefined) return the same thing as myFoo(null)?

Or, in yet another case, since myBar(1, 2, 3) is (almost) the same thing as myBar(1, 2, 3, undefined, undefined), should myBar(1, 2, 3, null, null) return the same thing as myBar(1, 2, 3)?

I feel that there's potential for confusion in both cases and that a library should probably follow a convention when handling null/undefined.

I'm not really asking for personal opinions (so please express those as comments rather than answers). I'm asking if anyone knows if there is a best practice that one should stick to when it comes to handling this distinction. References to external sources are very welcome!

I know very well that null and undefined are distinct in JavaScript. However, I can't seem to decide whether or not use that fact when my own functions are passed one of those as its argument.

Or, expressed in a different way, should myFoo(undefined) return the same thing as myFoo(null)?

Or, in yet another case, since myBar(1, 2, 3) is (almost) the same thing as myBar(1, 2, 3, undefined, undefined), should myBar(1, 2, 3, null, null) return the same thing as myBar(1, 2, 3)?

I feel that there's potential for confusion in both cases and that a library should probably follow a convention when handling null/undefined.

I'm not really asking for personal opinions (so please express those as comments rather than answers). I'm asking if anyone knows if there is a best practice that one should stick to when it comes to handling this distinction. References to external sources are very welcome!

Share Improve this question edited Jun 8, 2010 at 9:53 Jakob asked Jun 2, 2010 at 16:48 JakobJakob 24.4k8 gold badges47 silver badges58 bronze badges 2
  • 6 myBar(1, 2, 3) is not the same thing as myBar(1, 2, 3, undefined, undefined): the arguments object will have length of 3 in the first case and 5 in the second. – Tim Down Commented Jun 2, 2010 at 16:51
  • Ah, good point. Then I suppose its only the same thing if I explicitly receive five parameters and use them while ignoring the arguments object. – Jakob Commented Jun 2, 2010 at 16:56
Add a comment  | 

3 Answers 3

Reset to default 11 +100

I'd say that while, most of the time, there is little value in distinguishing between the two, the cases where there is value tend to be quite interesting.

Take, for example, a function which can be given a callback. undefined might indicate that some default callback should be used (as if the parameter weren't specified), but null could indicate that no callback should be made at all:

function asyncWorker(data, callback, timeout) {
    if (typeof callback === "undefined") {
        callback = function() { $("#log").append("<p>Done!</p>"); };
    }

    // ...

    if (callback) callback();
}

asyncWorker([1, 2, 3]); // default callback, no timeout
asyncWorker([4, 5, 6], null); // no callback, no timeout
asyncWorker([7, 8, 9], undefined, 10000); // default callback, 10s timeout

Of course, false or 0 could be used instead of null here, but that might not be the case in a more complex example. And whether your code benefits from the additional parameter complexity is entirely up to you. :-)

Best practice for handling arguments

  • define the expected arguments, what they will be used for, and the types of these
  • decide how they are accessed, either via the formal arguments, or through the arguments collection
  • define whether values outside the expected range should result in default values
  • verify that the arguments are within range before processing
  • for boolean values, decide whether they must be true booleans, or only truthy/falsy

Step 2, 3 and 4 is of most importance to you in this case

How to access the arguments
This is something you will need to select based on what the method does, and your strategy for handling a variable amount of arguments.

Take this for example

function foo() {
    var args = arguments.length == 1 ? 
        [document.body].concat([arguments[0]]) : 
        Array.prototype.slice.call(arguments);

    args[0].style.backgroundColor = args[1];
}

foo(document.body, "red");
foo("blue");​

True boolean or truthy/falsy
How to test for values depends largely on how your code is set up

function foo(elem, color) {
    if (!color) { // the correct test here should be 'typeof color == "undefined"'
        color = "green";
    }
    elem.style.backgroundColor = color;
}

foo(document.body, "red"); //set the background color to red
foo(document.body); //set the background color to the default green
foo(document.body, "");​ //remove the background color !This will fail!

The last statement will wrongly use the default value instead of the provided, even though the provided is within the expected range.

When it comes to handling undefined values remember that there is no difference in foo(undefined); and foo(); except that the length of the arguments collection will be different. How this is handled (and if it needs to be) is dependent on how you access the arguments.

Its entirely up to you how you handle arguments passed to your function, so its up to you. If you want to check if an argument is null you use

if (myVar === null) { 

and if you want to check if an argument is undefined you use

if (typeof myVar === "undefined") {

If the expected argument is anything other than 0, null or undefined, then you can check for this using

if (myVar) { 

So whether or not your myFoo(null) should behave the same as myFoo(undefined) is entirely up to how you handle these internally.

When it comes to extra parameters, this has no effect other than the arguments collection being larger than expected.

发布评论

评论列表(0)

  1. 暂无评论