为 JavaScript 函数设置默认参数值

IT技术 javascript function parameters arguments default-parameters
2021-01-22 04:46:06

我希望 JavaScript 函数具有可选参数,我将其设置为默认值,如果未定义值,则使用该参数(如果传递了值,则忽略)。在 Ruby 中,你可以这样做:

def read_file(file, delete_after = false)
  # code
end

这在 JavaScript 中有效吗?

function read_file(file, delete_after = false) {
  // Code
}
6个回答

ES6/ES2015 开始,默认参数在语言规范中。

function read_file(file, delete_after = false) {
  // Code
}

只是工作。

参考:默认参数 - MDN

如果传递未定义,默认函数参数允许使用默认值初始化形式参数

您还可以通过解构模拟默认命名参数

// the `= {}` below lets you call the function without any parameters
function myFor({ start = 5, end = 1, step = -1 } = {}) { // (A)
    // Use the variables `start`, `end` and `step` here
    ···
}

在 ES2015 之前

有很多方法,但这是我的首选方法——它可以让你传入任何你想要的东西,包括 false 或 null。( typeof null == "object")

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}
我知道这真的很小,但我不喜欢你的分配方式a = a以及b = b这些参数不是未定义的。此外,对于未来的维护者来说,条件有点复杂的三元运算符可能很难阅读。我更喜欢以下语法:if (typeof a == 'undefined') a = 42- 没有不必要的分配,而且更容易阅读。
2021-03-20 04:46:06
你也可以这样封装它:function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }然后你可以把它称为a = defaultFor(a, 42);
2021-03-23 04:46:06
有什么理由使用typeof吗?只是这样做似乎更简单a === undefined另外,如果你拼错了undefined,或者把它放在一个字符串中,你会得到一个参考错误
2021-03-26 04:46:06
@SiPlus 并且您在尝试使用undefined对象时免费获得了额外的引用错误:p 即使它可能适用于某些浏览器并且可能更快,null它仍然是一个对象并且undefined是对原始类型的引用,它试图告诉您存在这里什么都没有,甚至没有null在这里,简而言之,这两种情况:JavaScript/Reference/Global_Objects/undefined
2021-04-05 04:46:06
如果您检查对象的属性,则typeof是多余的。function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }这不会抛出引用错误并且简洁。
2021-04-05 04:46:06
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

这就赋予delete_after的valuedelete_after,如果它不是一个falsey值,否则将字符串"my default here"有关更多详细信息,请查看Doug Crockford 的语言调查并查看 Operators 部分

如果您想传入错误值,即false则此方法不起作用如果您需要传入 falsey值,则需要使用Tom Ritter's answer 中的方法nullundefined0""

在处理函数的多个参数时,允许使用者在对象中传递参数参数,然后这些值与包含函数默认值的对象合并通常很有用

function read_file(values) {
    values = merge({ 
        delete_after : "my default here"
    }, values || {});

    // rest of code
}

// simple implementation based on $.extend() from jQuery
function merge() {
    var obj, name, copy,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length;

    for (; i < length; i++) {
        if ((obj = arguments[i]) != null) {
            for (name in obj) {
                copy = obj[name];

                if (target === copy) {
                    continue;
                }
                else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    return target;
};

使用

// will use the default delete_after value
read_file({ file: "my file" }); 

// will override default delete_after value
read_file({ file: "my file", delete_after: "my value" }); 
在这种情况下,怎么delete_after没有得到表达式的布尔结果delete_after || "my default value"
2021-03-14 04:46:06
因为它不适用于虚假值,所以它可能会造成维护噩梦。一些之前一直传递真值的代码突然失败,因为在更强大的方法可用的情况下,应该避免传递假值。
2021-03-23 04:46:06
我觉得这还不够,因为我可能想传入 false。
2021-03-25 04:46:06
我发现它适用于大多数情况
2021-03-27 04:46:06
或者,您可以仅默认为 falsey 值 - 这通常是一个很好的默认值(例如,对于布尔值,为 false,对于字符串为空字符串,对于数字为 0 等) - 在这种情况下,实际上是什么并不重要通过了。
2021-03-27 04:46:06

我发现像这样简单的东西个人更简洁和可读。

function pick(arg, def) {
   return (typeof arg == 'undefined' ? def : arg);
}

function myFunc(x) {
  x = pick(x, 'my default');
} 
更新:如果您已经在使用underscore.js,我发现使用_.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. 使用此答案中所示的全局命名空间被许多人认为是一种不好的做法。util.default(arg, "defaul value")如果不想使用下划线,您也可以考虑为这个常见任务(例如滚动自己的实用程序,但我最终迟早会使用下划线,无论如何都没有重新发明轮子的意义。
2021-03-21 04:46:06
@Alnitak:仍然可以覆盖undefined. 因此,使用typeofand仍然是一个好主意'undefined'
2021-03-27 04:46:06
不要说 typeof arg == 'undefined',而是说 arg === undefined
2021-03-29 04:46:06
@OsamaBinLogin 你所说的对于当前的 JS 是正确的——旧的测试仍然存在,因为在某些浏览器上它曾经可以undefined用其他一些值覆盖,导致测试失败。
2021-03-29 04:46:06
我实际上推荐这个,我使用它并称之为“por”,代表“参数或”
2021-04-06 04:46:06

在 ECMAScript 6 中,您实际上将能够准确地编写您所拥有的内容:

function read_file(file, delete_after = false) {
  // Code
}

如果它不存在,这将设置delete_afterfalseundefined您可以使用ES6的功能,比如这一个今天transpilers如巴贝尔

有关更多信息,请参阅 MDN 文章

这是 ES6 的兼容性表kangax.github.io/compat-table/es6/#default_function_parameters不幸的是,尚不支持此语法
2021-03-10 04:46:06
等待浏览器获得 ECMAScript 6
2021-03-13 04:46:06
Babel 会把它转译成什么?
2021-03-22 04:46:06
2021-03-22 04:46:06
ECMAScript 6 我想......(我会自己更正,但我不能编辑 < 6 个字符)
2021-04-06 04:46:06

默认参数值

使用 ES6,您可以执行JavaScript与为函数参数设置默认值相关的最常见的习惯用法之一我们多年来这样做的方式应该看起来很熟悉:

function foo(x,y) {
 x = x || 11;
 y = y || 31;
 console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17

这种模式最常用,但当我们传递像这样的值时很危险

foo(0, 42)
foo( 0, 42 ); // 53 <-- Oops, not 42

为什么?因为0 is falsy, 所以x || 11 results in 11, 不是直接传入 0. 为了解决这个问题,有些人会像这样更详细地编写检查:

function foo(x,y) {
 x = (x !== undefined) ? x : 11;
 y = (y !== undefined) ? y : 31;
 console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17

我们现在可以检查添加的一个很好的有用的语法,ES6以简化将默认值分配给缺失参数的过程:

function foo(x = 11, y = 31) {
 console.log( x + y );
}

foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`

x = 11在函数声明中更像是x !== undefined ? x : 11比更常见的习语x || 11

默认值表达式

Function默认值可以不仅仅是像 31 这样的简单值;它们可以是任何有效的表达式,甚至是function call

function bar(val) {
 console.log( "bar called!" );
 return y + val;
}
function foo(x = y + 3, z = bar( x )) {
 console.log( x, z );
}
var y = 5;
foo(); // "bar called"
 // 8 13
foo( 10 ); // "bar called"
 // 10 15
y = 6;
foo( undefined, 10 ); // 9 10

如您所见,默认值表达式是惰性求值的,这意味着它们仅在需要时才运行——也就是说,当参数的参数被省略或未定义时。

默认值表达式甚至可以是内联函数表达式调用——通常称为立即调用函数表达式(IIFE)

function foo( x =
 (function(v){ return v + 11; })( 31 )
) {
 console.log( x );
}
foo(); // 42