首页 文章

设置JavaScript函数的默认参数值

提问于
浏览
2109

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

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

这适用于JavaScript吗?

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

21 回答

  • 5

    作为一个长期的C开发人员(Rookie to web development :)),当我第一次遇到这种情况时,我在函数定义中进行了参数赋值,就像在问题中提到的那样,如下所示 .

    function myfunc(a,b=10)
    

    但请注意,它不能跨浏览器一致地工作 . 对我来说,它在我的桌面上使用chrome,但在android上没有使用chrome . 如上所述,更安全的选择是 -

    function myfunc(a,b)
        {
        if (typeof(b)==='undefined') b = 10;
    ......
        }
    

    这个答案的意图不是重复相同的解决方案,而是其他人已经提到的,但是要告知函数定义中的参数赋值可能适用于某些浏览器,但不依赖于它 .

  • 139

    如果您使用的是 ES6+ ,则可以按以下方式设置默认参数:

    function test (foo = 1, bar = 2) {
      console.log(foo, bar);
    }
    
    test(5); // foo gets overwritten, bar remains default parameter
    

    如果需要 ES5 语法,可以按以下方式执行:

    function test(foo, bar) {
      foo = foo || 2;
      bar = bar || 0;
      
      console.log(foo, bar);
    }
    
    test(5); // foo gets overwritten, bar remains default parameter
    

    在上面的语法中,使用了 OR 运算符 . OR 运算符总是返回第一个值,如果它可以转换为 true ,如果不是,则返回右位置值 . 当调用该函数时没有相应的参数时,JS引擎将参数变量(在我们的示例中为 bar )设置为 undefined . undefined 然后转换为false,因此 OR 运算符返回值0 .

  • 3041

    在javascript中使用默认参数值时,我强烈建议极其谨慎 . 当与更高阶函数(如 forEachmapreduce )结合使用时,它通常会产生错误 . 例如,考虑以下代码行:

    ['1', '2', '3'].map(parseInt); // [1, NaN, NaN]
    

    parseInt有一个可选的第二个参数 function parseInt(s, [ radix =10]) 但是映射调用 parseInt 有三个参数:(元素,索引和数组) .

    我建议您将所需参数从可选/默认值参数中分离出来 . 如果您的函数需要1,2或3个必需参数,其默认值没有意义,请将它们作为函数的位置参数,任何可选参数都应该作为单个对象的命名属性 . 如果你的函数需要4个或更多,或许通过单个对象参数的属性提供所有参数更有意义 .

    在你的情况下,我建议你写这样的deleteFile函数:

    // unsafe
    function read_file(fileName, deleteAfter=false) {
        if (deleteAfter) {
            console.log(`Reading and then deleting ${fileName}`);
        } else {
            console.log(`Just reading ${fileName}`);
        }
    }
    
    // better
    function readFile(fileName, options={}) {
      const { deleteAfter = false } = options || {}; // if null
      read_file(fileName, deleteAfter);
    }
    
    console.log('unsafe...');
    ['log1.txt', 'log2.txt', 'log3.txt'].map(read_file);
    
    console.log('better...');
    ['log1.txt', 'log2.txt', 'log3.txt'].map(readFile);
    

    运行上面的代码片段说明了未使用参数的默认参数值背后隐藏的危险 .

  • 0

    如果由于某种原因你在ES6上 notare 使用lodash这里是一个通过_.defaultTo方法的默认函数参数的简明方法:

    var fn = function(a, b) {
      a = _.defaultTo(a, 'Hi')
      b = _.defaultTo(b, 'Mom!')
    
      console.log(a, b)
    }
    
    fn()                 // Hi Mom!
    fn(undefined, null)  // Hi Mom!
    fn(NaN, NaN)         // Hi Mom!
    fn(1)                // 1 "Mom!"
    fn(null, 2)          // Hi 2
    fn(false, false)     // false false
    fn(0, 2)             // 0 2
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
    

    如果当前值为 NaNnullundefined ,将设置默认值

  • 55

    Default Parameter Values

    使用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

    Default Value Expressions

    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
    
  • 2

    我发现像这样简单的东西更加简洁和个性化 .

    function pick(arg, def) {
       return (typeof arg == 'undefined' ? def : arg);
    }
    
    function myFunc(x) {
      x = pick(x, 'my default');
    }
    
  • 7

    是的,这将在Javascript中工作 . 你也可以这样做:

    function func(a=10,b=20)
    {
        alert (a+' and '+b);
    }
    
    func(); // Result: 10 and 20
    
    func(12); // Result: 12 and 20
    
    func(22,25); // Result: 22 and 25
    
  • 20

    根据语法

    function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
       statements
    }
    

    您可以定义形式参数的默认值 . 并使用 typeof 函数检查未定义的值 .

  • -3

    只需使用与undefined的显式比较 .

    function read_file(file, delete_after)
    {
        if(delete_after === undefined) { delete_after = false; }
    }
    
  • 569

    作为更新...使用ECMAScript 6,您可以 FINALLY 在函数参数声明中设置默认值,如下所示:

    function f (x, y = 7, z = 42) {
      return x + y + z
    }
    
    f(1) === 50
    

    如引用 - http://es6-features.org/#DefaultParameterValues

  • 1

    是的,这被称为默认参数

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

    句法:

    function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
       statements
    }
    

    Description:

    函数的参数默认为undefined但是,在某些情况下,设置不同的默认值可能很有用 . 这是默认参数可以帮助的地方 .

    过去,设置默认值的一般策略是测试函数体中的参数值,如果未定义则赋值 . 如果调用中未提供任何值,则其值将是未定义的 . 您必须设置条件检查以确保参数未定义

    使用ES2015中的默认参数,不再需要检查功能体 . 现在您只需在函数头中添加一个默认值即可 .

    差异示例:

    // OLD METHOD
    function multiply(a, b) {
      b = (typeof b !== 'undefined') ?  b : 1;
      return a * b;
    }
    
    multiply(5, 2); // 10
    multiply(5, 1); // 5
    multiply(5);    // 5
    
    
    // NEW METHOD
    function multiply(a, b = 1) {
      return a * b;
    }
    
    multiply(5, 2); // 10
    multiply(5, 1); // 5
    multiply(5);    // 5
    

    Different Syntax Examples:

    Padding undefined vs其他falsy值:

    即使在调用时显式设置了该值,num参数的值也是默认值 .

    function test(num = 1) {
      console.log(typeof num);
    }
    
    test();          // 'number' (num is set to 1)
    test(undefined); // 'number' (num is set to 1 too)
    
    // test with other falsy values:
    test('');        // 'string' (num is set to '')
    test(null);      // 'object' (num is set to null)
    

    在通话时评估:

    默认参数在调用时被计算,因此与其他语言不同,每次调用函数时都会创建一个新对象 .

    function append(value, array = []) {
      array.push(value);
      return array;
    }
    
    append(1); //[1]
    append(2); //[2], not [1, 2]
    
    
    // This even applies to functions and variables
    function callSomething(thing = something()) {
     return thing;
    }
    
    function something() {
      return 'sth';
    }
    
    callSomething();  //sth
    

    默认参数可用于以后的默认参数:

    已遇到的参数可用于以后的默认参数

    function singularAutoPlural(singular, plural = singular + 's',
                            rallyingCry = plural + ' ATTACK!!!') {
      return [singular, plural, rallyingCry];
    }
    
    //["Gecko","Geckos", "Geckos ATTACK!!!"]
    singularAutoPlural('Gecko');
    
    //["Fox","Foxes", "Foxes ATTACK!!!"]
    singularAutoPlural('Fox', 'Foxes');
    
    //["Deer", "Deer", "Deer ... change."]
    singularAutoPlural('Deer', 'Deer', 'Deer peaceably and respectfully \ petition the government for positive change.')
    

    函数体内定义的函数:

    在Gecko 33中引入(Firefox 33 / Thunderbird 33 / SeaMonkey 2.30) . 在函数体中声明的函数不能在默认参数中引用并抛出一个ReferenceError(当前是SpiderMonkey中的TypeError,参见bug 1022967) . 始终首先执行默认参数,然后在函数体内进行函数声明评估 .

    // Doesn't work! Throws ReferenceError.
    function f(a = go()) {
      function go() { return ':P'; }
    }
    

    默认参数后没有默认值的参数:

    在Gecko 26(Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2)之前,以下代码导致了SyntaxError . 这已在错误777060中修复,并在更高版本中按预期工作 . 参数仍然是从左到右设置,即使有没有默认值的后续参数,也会覆盖默认参数 .

    function f(x = 1, y) {
      return [x, y];
    }
    
    f(); // [1, undefined]
    f(2); // [2, undefined]
    

    具有默认值赋值的析构参数:

    您可以将默认值赋值与解构赋值表示法一起使用

    function f([x, y] = [1, 2], {z: z} = {z: 3}) {
      return x + y + z;
    }
    
    f(); // 6
    
  • 5
    def read_file(file, delete_after = false)
      # code
    end
    

    以下代码可能适用于这种情况,包括ECMAScript 6(ES6)以及早期版本 .

    function read_file(file, delete_after) {
        if(delete_after == undefined)
            delete_after = false;//default value
    
        console.log('delete_after =',delete_after);
    }
    read_file('text1.txt',true);
    read_file('text2.txt');
    

    当调用时跳过函数的参数值时,语言中的默认值有效,在JavaScript中,它被分配给 undefined . 这种方法在编程上看起来并不具有吸引力,但有 backward compatibility .

  • 1
    function throwIfNoValue() {
    throw new Error('Missing argument');
    }
    function foo(argValue = throwIfNoValue()) {
    return argValue ;
    }
    

    这里foo()是一个具有名为argValue的参数的函数 . 如果我们在函数调用中没有传递任何东西,那么将调用函数throwIfNoValue()并将返回的结果分配给唯一的参数argValue . 这是函数调用可以用作默认参数的方式 . 这使得代码更加简化和可读 .

    This example has been taken from here

  • 9

    如果要使用最新的 ECMA6 语法,请使用此选项:

    function myFunction(someValue = "This is DEFAULT!") {
      console.log("someValue --> ", someValue);
    }
    
    myFunction("Not A default value") // calling the function without default value
    myFunction()  // calling the function with default value
    

    它被称为default function parameters . 如果没有传递值或未定义,它允许使用默认值初始化形式参数 . NOTE :它不适用于Internet Explorer或旧版浏览器 .

    为了最大可能 compatibility 使用此:

    function myFunction(someValue) {
      someValue = (someValue === undefined) ? "This is DEFAULT!" : someValue;
      console.log("someValue --> ", someValue);
    }
    
    myFunction("Not A default value") // calling the function without default value
    myFunction()  // calling the function with default value
    

    这两个函数具有完全相同的行为,因为这些示例中的每一个都依赖于如果在调用该函数时没有传递参数值,则参数变量将为 undefined .

  • 6

    ES6: 正如大多数答案中已经提到的,在ES6中,您可以简单地初始化参数和值 .


    ES5: 大多数给定的答案对我来说都不够好,因为在某些情况下我可能需要将假设值 0nullundefined 传递给函数 . 要确定参数是否未定义,因为这是我传递的值而不是未定义的,因为根本没有定义,我这样做:

    function foo (param1, param2) {
       param1 = arguments.length >= 1 ? param1 : "default1";
       param2 = arguments.length >= 2 ? param2 : "default2";
    }
    
  • 2

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

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

    只是工作 .

    参考:Default Parameters - MDN

    默认函数参数允许在没有传递值或未定义的情况下使用默认值初始化形式参数 .

    你也可以simulate default named parameters via destructuring

    // 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
        ···
    }
    

    Pre ES2015

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

    function foo(a, b) {
      a = typeof a !== 'undefined' ? a : 42;
      b = typeof b !== 'undefined' ? b : 'default_b';
      ...
    }
    
  • 0
    function helloWorld(name, symbol = '!!!') {
        name = name || 'worlds';
        console.log('hello ' + name + symbol);
    }
    
    helloWorld(); // hello worlds!!!
    
    helloWorld('john'); // hello john!!!
    
    helloWorld('john', '(>.<)'); // hello john(>.<)
    
    helloWorld('john', undefined); // hello john!!!
    
    helloWorld(undefined, undefined); // hello worlds!!!
    
  • 2

    该解决方案适用于js:

    function read_file(file, delete_after) {
        delete_after = delete_after || false;
        // Code
    }
    
  • 1

    对于有兴趣在Microsoft Edge中使用代码工作的任何人,请不要在函数参数中使用默认值 .

    function read_file(file, delete_after = false) {
        #code
    }
    

    在该示例中,Edge将抛出错误“Expecting”)'“

    绕过这个用途

    function read_file(file, delete_after) {
      if(delete_after == undefined)
      {
        delete_after = false;
      }
      #code
    }
    

    截至2016年8月8日,这仍然是一个问题

  • 6

    在ECMAScript 6中,您实际上可以准确地写出您拥有的内容:

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

    如果不存在,则将 delete_after 设置为 falseundefined . 今天你可以使用像这样的ES6功能和Babel等转录器 .

    See the MDN article for more information .

  • 0
    function read_file(file, delete_after) {
        delete_after = delete_after || "my default here";
        //rest of code
    }
    

    如果它不是假值,则将 delete_after 的值分配给 delete_after ,否则它将分配字符串 "my default here" . 更多细节,看看Doug Crockford's survey of the language and check out the section on Operators .

    如果要传递假值,即 falsenullundefined0"" ,则此方法不起作用 . 如果您需要传递falsey值,则需要使用Tom Ritter's answer中的方法 .

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

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

相关问题