【问题标题】:Set a default parameter value for a JavaScript function为 JavaScript 函数设置默认参数值
【发布时间】:2010-10-28 01:09:54
【问题描述】:

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

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

这在 JavaScript 中有效吗?

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

【问题讨论】:

    标签: javascript function parameters arguments default-parameters


    【解决方案1】:

    来自ES6/ES2015,默认参数在语言规范中。

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

    刚刚好。

    参考:Default Parameters - MDN

    默认函数参数允许在传递no valueundefined时使用默认值初始化形式参数。

    你也可以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
        ···
    }
    

    ES2015 前

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

    function foo(a, b) {
      a = typeof a !== 'undefined' ? a : 42;
      b = typeof b !== 'undefined' ? b : 'default_b';
      ...
    }
    

    【讨论】:

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

    如果delete_after 的值不是falsey 值,则将其分配给delete_after,否则分配字符串"my default here"。更多详情,请查看Doug Crockford's survey of the language and check out the section on Operators

    如果您想传入 falsey 值,即 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" }); 
    

    【讨论】:

    • 我觉得这还不够,因为我可能想传入 false。
    • 我发现它在大多数情况下都足够了
    • 因为它不适用于虚假值,它可能会造成维护噩梦。在有更健壮的方法可用的情况下,应该避免使用以前总是传递真实值并由于传入虚假值而突然失败的代码。
    • 为什么delete_after没有得到表达式delete_after || "my default value"的布尔结果?
    • 或者,您可以只默认为 false 值 - 这通常是一个很好的默认值(例如,对于 bools 来说是 false,对于字符串来说是空字符串,对于数字来说是 0 等等) - 在这种情况下传入什么并不重要。
    【解决方案3】:

    我发现像这样简单的东西更简洁易读。

    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")),但我最终还是迟早会使用下划线,没有必要重新发明轮子。
    • 我真的很推荐这个,我用它叫它“por”,代表“参数或”
    • 不要说 typeof arg == 'undefined',而是说 arg === undefined
    • @OsamaBinLogin 你所说的对当前的 JS 是正确的 - 旧的测试仍然存在,因为在某些浏览器上,它曾经可以用其他值覆盖 undefined,导致测试失败。跨度>
    • @Alnitak:仍然可以覆盖undefined。所以,使用typeof'undefined' 仍然是一个好主意。
    【解决方案4】:

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

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

    这会将delete_after 设置为false(如果不存在)或undefined。您现在可以通过 Babel 等转译器来使用像这样的 ES6 功能。

    See the MDN article for more information

    【讨论】:

    【解决方案5】:

    默认参数值

    在 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
    

    【讨论】:

      【解决方案6】:

      该解决方案在 js 中对我有用:

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

      【讨论】:

      • 如果delete_after0null 会发生什么?它不适用于这些情况。
      • @StephanBijzitter 只有在某些情况下才会如此。但是,如果您只想使用默认值来取消设置值,这是行不通的,因为 0 或 null !=== false。
      • @Rutrus:你刚才说的我什么都听不懂。
      • delete_after = delete_after === undefined ? false : delete_after 呢?
      【解决方案7】:

      我强烈建议在 javascript 中使用默认参数值时要格外小心。当与forEachmapreduce 等高阶函数结合使用时,它通常会产生错误。例如,考虑这行代码:

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

      parseInt 有一个可选的第二个参数 function parseInt(s, [radix=10]) 但 map 调用 parseInt 时带有三个参数:(element, index数组)。

      我建议您将所需参数与可选/默认值参数分开。如果您的函数需要 1、2 或 3 个必需参数,而这些参数没有默认值,请将它们设为函数的位置参数,任何可选参数都应作为单个对象的命名属性跟随。如果您的函数需要 4 个或更多,那么通过单个对象参数的属性提供所有参数可能更有意义。

      在你的情况下,我建议你这样编写你的 deleteFile 函数:(edited per instead's cmets)...

      // 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 = !!(options && options.deleteAfter === true);
        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);

      运行上面的 sn-p 说明了隐藏在未使用参数的默认参数值背后的危险。

      【讨论】:

      • 这个“更好的解决方案”非常难以理解。我宁愿建议检查像typeof deleteAfter === 'bool' 这样的变量类型,否则抛出异常。另外,如果使用 map/foreach 等方法,请谨慎使用它们,并将调用的函数与匿名函数一起包装。 ['1', '2', '3'].map((value) =&gt; {read_file(value);})
      • 这是一个很好的观点。我试图避免在我的代码 sn-p 中使用库,但是这个成语在纯 javascript 中非常混乱。就个人而言,我会使用 lodash 的 get 方法来检索 deleteAfter。如果typeof 'deleteAfter' !== 'bool' 抛出异常也可能是一个很好的谨慎措施。我不喜欢设计要求调用者“谨慎使用”的方法。小心是函数的责任,而不是调用者的责任。最终行为应遵循最小意外原则。
      • 我同意,这个方法不应该这样写,调用它会破坏它的行为。但请记住,函数就像模型,调用者就像控制器。模型应该负责数据处理。函数(方法)应该期望数据,可以以错误的方式传递并处理它。这就是为什么检查参数类型加上抛出异常是最好的方法。尽管它更复杂。但它仍然可以让你免于挠头并不断问......为什么它不起作用?!然后......为什么它有效?!
      【解决方案8】:

      只需使用与未定义的显式比较。

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

      【讨论】:

        【解决方案9】:

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

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

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

        【讨论】:

        • 这个答案没有用,因为它是重复的
        【解决方案10】:

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

        function myfunc(a,b=10)
        

        但请注意,它在浏览器中的工作不一致。对我来说,它适用于我桌面上的 chrome,但不适用于 android 上的 chrome。 正如上面许多人提到的那样,更安全的选择是 -

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

        此答案的目的不是重复其他人已经提到的相同解决方案,而是告知函数定义中的参数分配可能适用于某些浏览器,但不要依赖它。

        【讨论】:

        • 函数定义中的赋值在 IE 11 中也不起作用,这是适用于 Windows 8.1 的 IE 的最新版本。
        • 如果有人想知道,function myfunc(a,b=10) 是 ES6 语法,其他答案中有指向兼容性表的链接。
        【解决方案11】:

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

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

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

        绕过这个用途

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

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

        【讨论】:

          【解决方案12】:

          如果您使用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)设置为undefinedundefined 然后转换为 false,因此 OR 运算符返回值 0。

          【讨论】:

            【解决方案13】:

            按照语法

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

            你可以定义形参的默认值。 并使用 typeof 函数检查未定义的值。

            【讨论】:

              【解决方案14】:
              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!!!
              

              【讨论】:

                【解决方案15】:

                如果你想使用最新的 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。如果没有传递任何值或未定义,它允许使用默认值初始化形式参数。 注意:它不适用于 Internet Explorer 或更旧的浏览器。

                为了最大可能的兼容性使用这个:

                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

                【讨论】:

                • 注意:正如@BlackBeard 所说,function(param=value) 不适用于 IE。使用兼容版本。
                【解决方案16】:

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


                ES5:大多数给出的答案对我来说不够好,因为在某些情况下我可能不得不将错误值(例如 0nullundefined 传递给一个函数。要确定参数是否未定义,因为这是我传递的值而不是由于根本没有定义而未定义的值,我这样做:

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

                【讨论】:

                  【解决方案17】:

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

                  这里的 foo() 是一个函数,它有一个名为 argValue 的参数。如果我们在此处的函数调用中不传递任何内容,则将调用函数 throwIfNoValue(),并将返回的结果分配给唯一的参数 argValue。这就是函数调用可以用作默认参数的方式。这使得代码更加简化和可读。

                  This example has been taken from here

                  【讨论】:

                    【解决方案18】:

                    如果由于某种原因你在 ES6 上不是并且正在使用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
                    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"&gt;&lt;/script&gt;

                    如果当前值为 NaNnullundefined

                    ,将设置默认值

                    【讨论】:

                      【解决方案19】:

                      是的,ES6 完全支持使用默认参数:

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

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

                      但在 ES5 之前,您可以轻松做到这一点:

                      function read_file(file, delete_after) {
                        var df = delete_after || false;
                        // Code
                      }
                      

                      这意味着如果该值存在,则使用该值,否则,使用 || 操作之后的第二个值,它执行相同的操作...

                      注意: 如果你将一个值传递给 ES6 两者之间也有很大的不同,即使该值是虚假的,也会被新值替换,某事像 null""... 但 ES5 只有在传递的值是真实的情况下才会替换一个,那是因为 || 的工作方式...

                      【讨论】:

                        【解决方案20】:

                        未来之声

                        将来,您将能够将一个对象“传播”到另一个对象(目前截至 2019 年 NOT supported by Edge!) - 演示如何将其用于不错的默认选项,而不管顺序如何:

                        function test(options) {
                            var options = {
                               // defaults
                               url: 'defaultURL',
                               some: 'somethingDefault',
                               // override with input options
                               ...options
                            };
                            
                            var body = document.getElementsByTagName('body')[0];
                            body.innerHTML += '<br>' + options.url + ' : ' + options.some;
                        }
                        test();
                        test({});
                        test({url:'myURL'});
                        test({some:'somethingOfMine'});
                        test({url:'overrideURL', some:'andSomething'});
                        test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

                        MDN 参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

                        ...同时Edge DOES support is Object.assign() (IE 没有,但我真的希望我们可以将 IE 抛在后面:))

                        你也可以这样做

                            function test(options) {
                                var options = Object.assign({
                                   // defaults
                                   url: 'defaultURL',
                                   some: 'somethingDefault',
                                }, options); // override with input options
                                
                                var body = document.getElementsByTagName('body')[0];
                                body.innerHTML += '<br>' + options.url + ' : ' + options.some;
                            }
                            test();
                            test({});
                            test({url:'myURL'});
                            test({some:'somethingOfMine'});
                            test({url:'overrideURL', some:'andSomething'});
                            test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

                        编辑:由于 cmets 关于 const 选项 - 在函数的其余部分使用常量选项的问题实际上是 不是 你不能这样做,只是你不能在自己的声明中使用常量变量 - 你必须将输入命名调整为类似

                        function test(input_options){
                           const options = {
                             // defaults
                             someKey:    'someDefaultValue',
                             anotherKey: 'anotherDefaultValue',
                        
                             // merge-in input options
                             ...input_options
                           };
                        
                           // from now on use options with no problem
                        }
                        

                        【讨论】:

                        • 问题是你通常不想这样做,因为这会重新分配已经定义的选项,但你可以将它与其他合法的 var 一起使用。
                        • function test(options) { /* 选项已定义,如果你现在使用 const options = {} 会抛出错误*/ }
                        • 当你创建一个函数并且你作为参数名选项传入时不是全局的,然后在函数内部定义选项在函数(opt){} opt被定义你不能在里面使用const opt函数那么这很糟糕,因为如果你经常这样做,你会重新分配变量,看起来你的一般模式这是一个问题
                        • @google-frank-dspeed 啊,你的意思是你不能做function(opt){ const opt = /*some merging*/; }这肯定行不通,因为你会使用const 变量在它被声明之前 - 你必须调整 - function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
                        • @google-frank-dspeed 无论如何,更多的新人可能会对此感到疑惑,所以我添加了操作方法代码以进行编辑 :) 所以感谢您为其他人指出这一点 :)跨度>
                        【解决方案21】:

                        只是为了展示我的技能(笑),即使没有如下命名参数也可以编写上述函数:

                        ES5 及以上

                        function foo() {
                            a = typeof arguments[0] !== 'undefined' ? a : 42;
                            b = typeof arguments[1] !== 'undefined' ? b : 'default_b';
                            ...
                        }
                        

                        ES6 及以上

                        function foo(...rest) {
                            a = typeof rest[0] !== 'undefined' ? a : 42;
                            b = typeof rest[1] !== 'undefined' ? b : 'default_b';
                            ...
                        }
                        

                        【讨论】:

                          【解决方案22】:

                          是的,这被称为默认参数

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

                          语法:

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

                          说明:

                          函数的参数默认为 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
                          

                          不同的语法示例:

                          填充未定义与其他虚假值:

                          即使调用时显式设置了值,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
                          

                          【讨论】:

                            【解决方案23】:

                            我注意到一些答案提到使用默认参数不能移植到其他浏览器,但公平地说,您可以使用 Babel 之类的转译器将代码转换为支持有限的浏览器的 ES5 语法用于现代 JS 功能。

                            所以这个:

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

                            将被编译成这样(在 Babel REPL 中尝试一下 -> https://babeljs.io/repl/):

                            "use strict";
                            
                            function read_file(file) {
                            
                              var delete_after =
                                arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
                              
                              //Code...
                            
                            }
                            

                            当然,如果您不打算使用转译,那么像其他人演示的那样在函数体中设置默认参数也很好。

                            【讨论】:

                              【解决方案24】:
                              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。这种方法在编程上看起来并不吸引人,但具有向后兼容性

                              【讨论】:

                                【解决方案25】:

                                设置默认参数的另一种方法是使用参数的对象映射,而不是直接使用参数。 例如,

                                const defaultConfig = {
                                 category: 'Animals',
                                 legs: 4
                                };
                                
                                function checkOrganism(props) {
                                 const category = props.category || defaultConfig.category;
                                 const legs = props.legs || defaultConfig.legs;
                                }
                                

                                这样,很容易扩展参数,不用担心参数长度不匹配。

                                【讨论】:

                                  【解决方案26】:

                                  是的 - 证明:

                                  function read_file(file, delete_after = false) {
                                    // Code
                                    console.log({file,delete_after});
                                  }
                                  
                                  
                                  
                                  // TEST
                                  read_file("A");
                                  read_file("B",true);
                                  read_file("C",false);

                                  【讨论】:

                                    【解决方案27】:
                                    export const getfilesize = (bytes, decimals = 2) => {
                                        if (bytes === 0){ 
                                            return '0 Bytes';
                                        }else{
                                            const k = 1024;
                                            const dm = decimals < 0 ? 0 : decimals;
                                            const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
                                            const i = Math.floor(Math.log(bytes) / Math.log(k));
                                            return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
                                    
                                        }
                                    }
                                    

                                    【讨论】:

                                      【解决方案28】:

                                      答案是肯定的。事实上,支持默认参数的语言有很多。 Python 就是其中之一:

                                      def(a, enter="Hello"):
                                         print(a+enter)
                                      

                                      尽管由于括号这是 Python 3 代码,但函数中的默认参数也适用于 JS。

                                      例如,在你的情况下:

                                      function read_file(file, deleteAfter=false){
                                        console.log(deleteAfter);
                                      }
                                      
                                      read_file("test.txt");

                                      但有时你并不需要默认参数。

                                      您可以在函数开始后立即定义变量,如下所示:

                                      function read_file(file){
                                        var deleteAfter = false;
                                        console.log(deleteAfter);
                                      }
                                      
                                      read_file("test.txt");

                                      在我的两个示例中,它返回相同的内容。但有时它们实际上可能很有用,比如在非常高级的项目中。

                                      所以,总而言之,JS 中可以使用默认参数值。但这与在函数开始后立即定义变量几乎相同。但是,有时它们仍然非常有用。您可能已经注意到,默认参数值比在函数开始后立即定义参数的标准方式少了 1 行代码。

                                      编辑: 这非常重要!这将在 IE 中工作。见documentation。因此,对于 IE,您必须使用“在函数顶部定义变量”方法。默认参数在 IE 中不起作用。

                                      【讨论】:

                                        【解决方案29】:

                                        是的,这将在 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
                                        

                                        【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 2013-01-01
                                        • 2013-04-28
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2016-11-03
                                        • 2014-04-25
                                        相关资源
                                        最近更新 更多