我是否总是使用“||' 以指定默认参数值

Can I always use `||` to assign default parameter values?

本文关键字:参数 默认 是否      更新时间:2023-09-26

可选参数

我经常有带有可选参数的 JavaScript 函数。而不是像这样写一张长支票:

if(param === null || param === undefined){ 
    param = {};
}

我通常使用以下语法:

function doSomething(optionalParam, optionalCallback, optionalFlag){
    optionalParam = optionalParam || {};
    optionalParam["xyz"] = "value";    //Won't fail if the user didn't pass a value
    optionalCallback = optionalCallback || function(){};
    optionalCallback();        //If I need the function on 20 places, I don't have to insert a typeof-check everywhere
    optionalFlag = optionalFlag || false;
}

优势很明显,我可以处理undefinednull参数。

但是,这不适用于默认为 true 的可选标志:

someFlag = someFlag || true; //Will never evaluate to false.

返回值

下面是我使用该语法的另一个示例:

function getValueOfIndex(idx){
    return anArray[idx] || null;  //Returns null if the index is out of bounds
}

我的问题:

||运算符在我的用例中如何工作?

  • 我可以在所有这些情况下使用 || 吗?
  • 有什么理由不使用它吗?
  • 是否有任何其他类型或值会导致此语法失败?

编辑:我认识到我的最后一点(null||undefinedundefined||null之间的差异)应该属于一个单独的问题,所以我删除了它。

一般的答案是你不能使用

parameter = parameter || default;

如果用户应该能够传递 false 的显式参数,并且该参数应优先于默认值。在这种情况下,您需要显式测试undefined

parameter = typeof parameter == "undefined" ? default : parameter;

如果用户应该能够传递显式undefined值并使其优先(这是非常反常的做法),则需要测试arguments.length以确定传递了多少参数,因此只能默认剩余参数。

为什么以下两个表达式返回不同的值?

  • null || undefined//求值为 undefined
  • 未定义 || null//计算结果为 null
something

|| somethingElse 是一个表达式,这意味着它将始终返回一个值,要么是第一个真值,要么是最后一个值。例如false || 17是 17。null 和 undefined 都是假的,所以在这两种情况下,||将返回最后一个值。

我可以在所有这些情况下使用 || 吗?

||有时可以做一些你意想不到的事情

function thisIsUnexpected (a) {
    a = a || "other value";
    reurn a;
}
thisIsUnexpected(); // will return "other value";
// it can fail when you pass in a falsy value
thisIsUnexpected(false); // you would want it to return false, yet it will return "other value"

若要获得正确的行为,需要按如下所示使用三元表达式。这永远不会失败。

function thisIsExpected (a) {
    a = (a === undefined) ? "other value" : a;
    reurn a;
}

只要用于测试参数是否存在的表达式对于提供参数的所有情况都返回 true,就可以使用逻辑 OR 运算符。

someFlag = someFlag || true; //Will never evaluate to false.

您上面的例子不起作用,因为我可以提供参数false并且用于测试参数是否存在的表达式(在这种情况下只是someFlag)仍将计算为 false,这意味着未指定参数。

因此,您需要将代码修改为:

someFlag = (typeof someFlag === 'boolean') ? someFlag : true;