处理JavaScript中undefined-和null-parameters之间的区别

时间:2010-06-02 16:48:19

标签: javascript

我非常清楚在JavaScript中null和undefined是不同的。但是,当我自己的函数被传递给其中一个作为其参数时,我似乎无法决定是否使用该事实。

或者,以不同的方式表达,myFoo(undefined)应该返回与myFoo(null)相同的内容吗?

或者,在另一种情况下,由于myBar(1, 2, 3)(几乎)与myBar(1, 2, 3, undefined, undefined)相同,myBar(1, 2, 3, null, null)应该返回与myBar(1, 2, 3)相同的内容吗?

我觉得在这两种情况下都存在混淆的可能性,并且在处理null / undefined时,库应该遵循约定。

我并不是真的要求个人意见(所以请将这些意见表达为评论而非答案)。我问是否有人知道在处理这种区别时是否应该坚持最佳做法。非常欢迎参考外部资源!

3 个答案:

答案 0 :(得分:11)

我会说,虽然大部分时间,区分两者的价值不大, 值的情况往往非常有趣。

例如,举一个可以给予回调的函数。 undefined可能表示应该使用某些默认回调(就好像未指定参数一样),但null可能表示根本不应该进行回调:

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

当然,这里可以使用false0代替null,但在更复杂的示例中可能不是这种情况。您的代码是否受益于额外的参数复杂性完全取决于您。 : - )

答案 1 :(得分:2)

处理参数的最佳做法

  • 定义预期的参数,它们将用于什么,以及这些
  • 的类型
  • 通过正式参数或arguments集合
  • 决定 访问方式
  • 定义超出预期范围的值是否应该导致默认值
  • 验证参数在处理之前是否在范围内
  • 表示布尔值,决定它们是否必须为真正的布尔值,或仅 truthy / falsy

在这种情况下,第2,3和4步对您来说非常重要

如何访问参数
这是您需要根据方法所做的以及处理可变数量参数的策略来选择的。

以此为例

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");​

真布尔或真实/虚假
如何测试值主要取决于代码的设置方式

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!

最后一个语句将错误地使用默认值而不是提供的值,即使提供的值在预期范围内。

在处理undefined值时,请记住foo(undefined);foo(); 除了之外没有区别arguments的长度收藏会有所不同。如何处理(如果需要)取决于您如何访问参数。

答案 2 :(得分:0)

完全取决于你如何处理传递给你的函数的参数,所以它取决于你。 如果要检查参数是否为null,请使用

if (myVar === null) { 

如果您想检查参数是否为undefined,请使用

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

如果期望的参数不是0,null或undefined,那么您可以使用

检查
if (myVar) { 

因此,myFoo(null)的行为是否应与myFoo(undefined)相同,完全取决于您如何在内部处理这些问题。

当涉及额外参数时,除了arguments集合大于预期之外,这没有任何影响。