首页 文章

有没有更好的方法在JavaScript中执行可选的函数参数? [重复]

提问于
浏览
770

这个问题在这里已有答案:

我总是在JavaScript中处理可选参数,如下所示:

function myFunc(requiredArg, optionalArg){
  optionalArg = optionalArg || 'defaultValue';

  // Do stuff
}

有没有更好的方法呢?

是否有任何使用 || 的情况会失败?

28 回答

  • -2

    我建议你这样使用ArgueJS

    function myFunc(){
      arguments = __({requiredArg: undefined, optionalArg: [undefined: 'defaultValue'})
    
      //do stuff, using arguments.requiredArg and arguments.optionalArg
      //    to access your arguments
    
    }
    

    您还可以使用您希望接收的参数类型替换 undefined ,如下所示:

    function myFunc(){
      arguments = __({requiredArg: Number, optionalArg: [String: 'defaultValue'})
    
      //do stuff, using arguments.requiredArg and arguments.optionalArg
      //    to access your arguments
    
    }
    
  • 125
    function foo(requiredArg){
      if(arguments.length>1) var optionalArg = arguments[1];
    }
    
  • 1026

    你可以使用一些不同的方案 . 我一直在测试arguments.length:

    function myFunc(requiredArg, optionalArg){
      optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg;
    
      ...
    
    • 这样做,它不可能失败,但我不知道你的方式是否有任何失败的机会,刚才我想不出一个场景,它实际上会失败...

    然后保罗提供了一个失败的场景! - )

  • 32

    理想情况下,您将重构一个对象并使用默认对象传递它,因此传递参数的顺序无关紧要(请参阅下面的答案的第二部分) .

    但是,如果您只想要快速,可靠,易于使用且不笨重的东西,请尝试以下方法:


    对任意数量的默认参数进行简洁快速修复

    • 它优雅地扩展:每个新默认值的最小额外代码

    • 您可以将其粘贴到任何位置:只需更改所需的参数和变量的数量

    • 如果要将 undefined 传递给具有默认值的参数,这样,该变量将设置为 undefined . 此页面上的大多数其他选项将使用默认值替换 undefined .

    这是一个为三个可选参数提供默认值的示例(带有两个必需参数)

    function myFunc( requiredA, requiredB,  optionalA, optionalB, optionalC ) {
    
      switch (arguments.length - 2) { // 2 is the number of required arguments
        case 0:  optionalA = 'Some default';
        case 1:  optionalB = 'Another default';
        case 2:  optionalC = 'Some other default';
        // no breaks between cases: each case implies the next cases are also needed
      }
    
    }
    

    Simple demo . 这与roenving's answer类似,但可以轻松扩展为任意数量的默认参数,更易于更新,并且using arguments not Function.arguments .


    传递和合并对象以获得更大的灵活性

    上述代码与许多执行默认参数的方法一样,不能不按顺序传递参数,例如,传递 optionalC 但是让 optionalB 回退到默认值 .

    一个很好的选择是传递对象并与默认对象合并 . 这也有利于可维护性(只需注意保持代码可读,因此未来的合作者不会猜测您传递的对象的可能内容) .

    使用jQuery的示例 . 如果你不't use jQuery, you could instead use Underscore' s _.defaults(object, defaults)browse these options

    function myFunc( args ) {
      var defaults = {
        optionalA: 'Some default',
        optionalB: 'Another default',
        optionalC: 'Some other default'
      };
      args = $.extend({}, defaults, args);
    }
    

    这是a simple example of it in action .

  • 2

    我发现这是最简单,最易读的方式:

    if (typeof myVariable === 'undefined') { myVariable = 'default'; }
    //use myVariable here
    

    Paul Dixon的回答(以我的拙见)不如此可读,但归结为偏好 .

    insin的答案要先进得多,但对大功能更有用!

    EDIT 11/17/2013 9:33pm: 我为Node.js创建了一个包,使"overload"函数(方法)更容易被称为parametric .

  • 44

    这就是我最终的结果:

    function WhoLikesCake(options) {
      options = options || {};
      var defaultOptions = {
        a : options.a || "Huh?",
        b : options.b || "I don't like cake."
      }
      console.log('a: ' + defaultOptions.b + ' - b: ' + defaultOptions.b);
    
      // Do more stuff here ...
    }
    

    这样称呼:

    WhoLikesCake({ b : "I do" });
    
  • 124

    伙计 -

    在查看了这些和其他解决方案之后,我尝试使用最初来自W3Schools的一段代码作为基础来解决其中的一些问题 . 您可以找到以下内容 . 每个注释掉的项目都可以正常工作,这样您就可以通过删除单个注释来进行实验 . 需要说明的是,未定义的是“eyecolor”参数 .

    function person(firstname, lastname, age, eyecolor)
    {
    this.firstname = firstname;
    this.lastname = lastname;
    this.age = age;
    this.eyecolor = eyecolor;
    // if(null==eyecolor)
    //   this.eyecolor = "unknown1";
    //if(typeof(eyecolor)==='undefined') 
    //   this.eyecolor = "unknown2";
    // if(!eyecolor)
    //   this.eyecolor = "unknown3";
    this.eyecolor = this.eyecolor || "unknown4";
    }
    
    var myFather = new person("John", "Doe", 60);
    var myMother = new person("Sally", "Rally", 48, "green");
    
    var elem = document.getElementById("demo");
    elem.innerHTML = "My father " +
                  myFather.firstname + " " +
                  myFather.lastname + " is " +
                  myFather.age + " with " +
                  myFather.eyecolor + " eyes.
    " + "My mother " + myMother.firstname + " " + myMother.lastname + " is " + myMother.age + " with " + myMother.eyecolor + " eyes.";
  • 0

    在ECMAScript 2015(又名“ES6”)中,您可以在函数声明中声明默认参数值:

    function myFunc(requiredArg, optionalArg = 'defaultValue') {
        // do stuff
    }
    

    更多关于他们的事情this article on MDN(尽管有文章 Headers ,他们在JavaScript中被称为"arguments,"而不是"parameters,") .

    目前这是only supported by Firefox,但随着标准的完成,预计支持将迅速提升 .

  • 1

    我习惯于看到处理可选变量的一些基本变化 . 有时,轻松的版本很有用 .

    function foo(a, b, c) {
      a = a || "default";   // Matches 0, "", null, undefined, NaN, false.
      a || (a = "default"); // Matches 0, "", null, undefined, NaN, false.
    
      if (b == null) { b = "default"; } // Matches null, undefined.
    
      if (typeof c === "undefined") { c = "default"; } // Matches undefined.
    }
    

    例如,在Backbone.js中广泛使用了与变量 a 一起使用的虚假默认值 .

  • 0

    登陆这个问题,搜索 default parameters in EcmaScript 2015 ,因此只提......

    使用 ES6 ,我们可以default parameters

    function doSomething(optionalParam = "defaultValue"){
        console.log(optionalParam);//not required to check for falsy values
    }
    
    doSomething(); //"defaultValue"
    doSomething("myvalue"); //"myvalue"
    
  • 3

    如果您需要查看文字 NULL ,那么您可能会遇到一些问题 . 除此之外,不,我认为你可能走在正确的轨道上 .

    一些人选择的另一种方法是在参数列表中迭代一组关联变量 . 它看起来有点整洁,但我想它有点(非常小)一点点进程/内存密集 .

    function myFunction (argArray) {
        var defaults = {
            'arg1'  :   "value 1",
            'arg2'  :   "value 2",
            'arg3'  :   "value 3",
            'arg4'  :   "value 4"
        }
    
        for(var i in defaults) 
            if(typeof argArray[i] == "undefined") 
                   argArray[i] = defaults[i];
    
        // ...
    }
    
  • 1

    我没有't know why @Paul'的回复被低估,但对 null 的验证是一个不错的选择 . 也许一个更肯定的例子会更有意义:

    在JavaScript中,一个遗漏的参数就像一个未初始化的声明变量(只是 var a1; ) . 等于运算符将undefined转换为null,因此这对值类型和对象都很有效,这就是CoffeeScript处理可选参数的方式 .

    function overLoad(p1){
        alert(p1 == null); // Caution, don't use the strict comparison: === won't work.
        alert(typeof p1 === 'undefined');
    }
    
    overLoad(); // true, true
    overLoad(undefined); // true, true. Yes, undefined is treated as null for equality operator.
    overLoad(10); // false, false
    
    
    function overLoad(p1){
        if (p1 == null) p1 = 'default value goes here...';
        //...
    }
    

    尽管如此,有人担心最好的语义是 typeof variable === 'undefined' 稍好一些 . 我'm not about to defend this since it'是底层API如何实现一个功能的问题;它不应该对API用户感兴趣 .

    我还应该补充一点,这里是物理上确保错过任何参数的唯一方法,使用 in 运算符,遗憾的是它不能使用参数名称,因此必须传递 arguments 的索引 .

    function foo(a, b) {
        // Both a and b will evaluate to undefined when used in an expression
        alert(a); // undefined
        alert(b); // undefined
    
        alert("0" in arguments); // true
        alert("1" in arguments); // false
    }
    
    foo (undefined);
    
  • 8

    Loose type checking

    容易写,但 0'' ,_ falsenullundefined 将转换为默认值,这可能不是预期的结果 .

    function myFunc(requiredArg, optionalArg) {
        optionalArg = optionalArg || 'defaultValue';
    }
    

    Strict type checking

    更长,但涵盖了大多数情况 . 只有错误地指定默认值的情况才是我们传递 undefined 作为参数 .

    function myFunc(requiredArg, optionalArg) {
        optionalArg = typeof optionalArg !== 'undefined' ? optionalArg : 'defaultValue';
    }
    

    Checking arguments variable

    捕获所有案例,但写起来最笨拙 .

    function myFunc(requiredArg, optionalArg1, optionalArg2) {
        optionalArg1 = arguments.length > 1 ? optionalArg1 : 'defaultValue';
        optionalArg2 = arguments.length > 2 ? optionalArg2 : 'defaultValue';
    }
    

    ES6

    不幸的是,目前浏览器支持很差

    function myFunc(requiredArg, optionalArg = 'defaultValue') {
    
    }
    
  • 5

    如果传递了OptionalArg,您的逻辑将失败,但计算结果为false - 请尝试将其作为替代方法

    if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }
    

    或另类成语:

    optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;
    

    使用最适合您的意图传达最佳意图!

  • 1

    在一个项目中,我注意到我使用可选参数和设置重复了太多,所以我创建了一个处理类型检查的类,并分配一个默认值,从而产生整洁可读的代码 . 请参阅示例,让我知道这是否适合您 .

    var myCar           = new Car('VW', {gearbox:'automatic', options:['radio', 'airbags 2x']});
    var myOtherCar      = new Car('Toyota');
    
    function Car(brand, settings) {
        this.brand      = brand;
    
        // readable and adjustable code
        settings        = DefaultValue.object(settings, {});
        this.wheels     = DefaultValue.number(settings.wheels, 4);
        this.hasBreaks  = DefaultValue.bool(settings.hasBreaks, true);
        this.gearbox    = DefaultValue.string(settings.gearbox, 'manual');
        this.options    = DefaultValue.array(settings.options, []);
    
        // instead of doing this the hard way
        settings        = settings || {};
        this.wheels     = (!isNaN(settings.wheels)) ? settings.wheels : 4;
        this.hasBreaks  = (typeof settings.hasBreaks !== 'undefined') ? (settings.hasBreaks === true) : true;
        this.gearbox    = (typeof settings.gearbox === 'string') ? settings.gearbox : 'manual';
        this.options    = (typeof settings.options !== 'undefined' && Array.isArray(settings.options)) ? settings.options : [];
    }
    

    使用这个类:

    (function(ns) {
    
        var DefaultValue = {
    
            object: function(input, defaultValue) {
                if (typeof defaultValue !== 'object') throw new Error('invalid defaultValue type');
                return (typeof input !== 'undefined') ? input : defaultValue;
            },
    
            bool: function(input, defaultValue) {
                if (typeof defaultValue !== 'boolean') throw new Error('invalid defaultValue type');
                return (typeof input !== 'undefined') ? (input === true) : defaultValue;
            },
    
            number: function(input, defaultValue) {
                if (isNaN(defaultValue)) throw new Error('invalid defaultValue type');
                return (typeof input !== 'undefined' && !isNaN(input)) ? parseFloat(input) : defaultValue;
            },
    
            // wrap the input in an array if it is not undefined and not an array, for your convenience
            array: function(input, defaultValue) {
                if (typeof defaultValue === 'undefined') throw new Error('invalid defaultValue type');
                return (typeof input !== 'undefined') ? (Array.isArray(input) ? input : [input]) : defaultValue;
            },
    
            string: function(input, defaultValue) {
                if (typeof defaultValue !== 'string') throw new Error('invalid defaultValue type');
                return (typeof input === 'string') ? input : defaultValue;
            },
    
        };
    
        ns.DefaultValue = DefaultValue;
    
    }(this));
    
  • 1

    未定义的测试是不必要的,并且不像它可能那样健壮,因为正如user568458所指出的,如果传递null或false,则提供的解决方案将失败 . API的用户可能会认为为false或null会强制该方法避免该参数 .

    function PaulDixonSolution(required, optionalArg){
       optionalArg = (typeof optionalArg === "undefined") ? "defaultValue" : optionalArg;
       console.log(optionalArg);
    };
    PaulDixonSolution("required");
    PaulDixonSolution("required", "provided");
    PaulDixonSolution("required", null);
    PaulDixonSolution("required", false);
    

    结果是:

    defaultValue
    provided
    null
    false
    

    最后两个可能是坏的 . 而是尝试:

    function bulletproof(required, optionalArg){
       optionalArg = optionalArg ? optionalArg : "defaultValue";;
       console.log(optionalArg);
    };
    bulletproof("required");
    bulletproof("required", "provided");
    bulletproof("required", null);
    bulletproof("required", false);
    

    结果如下:

    defaultValue
    provided
    defaultValue
    defaultValue
    

    这不是最佳的唯一情况是当你实际上有可选参数,意味着布尔值或故意空值 .

  • -1

    在OptionalArg为假的所有情况下,您最终会得到defaultValue .

    function myFunc(requiredArg, optionalArg) {
        optionalArg = optionalArg || 'defaultValue';
        console.log(optionalArg);
        // Do stuff
    }
    myFunc(requiredArg);
    myFunc(requiredArg, null);
    myFunc(requiredArg, undefined);
    myFunc(requiredArg, "");
    myFunc(requiredArg, 0);
    myFunc(requiredArg, false);
    

    所有上面的日志都是defaultValue,因为所有6都是假的 . 在第4,5,6项情况下,您可能没有兴趣将optionalArg设置为defaultValue,但它设置为因为它们是假的 .

  • -1
    • arg || 'default' 是一种很好的方式,适用于90%的情况

    • 当您需要传递可能是'falsy'的值时失败

    • false

    • 0

    • NaN

    • ""

    对于这些情况,您需要更加冗长并检查 undefined

    • 首先要有可选参数时要小心,你必须要知道所有参数的类型
  • 2

    如果你正在使用Underscore库(你应该,它是一个很棒的库):

    _.defaults(optionalArg, 'defaultValue');
    
  • 17
    function Default(variable, new_value)
    {
        if(new_value === undefined) { return (variable === undefined) ? null : variable; }
        return (variable === undefined) ? new_value : variable;
    }
    
    var a = 2, b = "hello", c = true, d;
    
    var test = Default(a, 0),
    test2 = Default(b, "Hi"),
    test3 = Default(c, false),
    test4 = Default(d, "Hello world");
    
    window.alert(test + "\n" + test2 + "\n" + test3 + "\n" + test4);
    

    http://jsfiddle.net/mq60hqrf/

  • 3

    与Oli的答案类似,我使用一个参数Object和一个定义默认值的Object . 带点糖......

    /**
     * Updates an object's properties with other objects' properties. All
     * additional non-falsy arguments will have their properties copied to the
     * destination object, in the order given.
     */
    function extend(dest) {
      for (var i = 1, l = arguments.length; i < l; i++) {
        var src = arguments[i]
        if (!src) {
          continue
        }
        for (var property in src) {
          if (src.hasOwnProperty(property)) {
            dest[property] = src[property]
          }
        }
      }
      return dest
    }
    
    /**
     * Inherit another function's prototype without invoking the function.
     */
    function inherits(child, parent) {
      var F = function() {}
      F.prototype = parent.prototype
      child.prototype = new F()
      child.prototype.constructor = child
      return child
    }
    

    ......这可以做得更好一些 .

    function Field(kwargs) {
      kwargs = extend({
        required: true, widget: null, label: null, initial: null,
        helpText: null, errorMessages: null
      }, kwargs)
      this.required = kwargs.required
      this.label = kwargs.label
      this.initial = kwargs.initial
      // ...and so on...
    }
    
    function CharField(kwargs) {
      kwargs = extend({
        maxLength: null, minLength: null
      }, kwargs)
      this.maxLength = kwargs.maxLength
      this.minLength = kwargs.minLength
      Field.call(this, kwargs)
    }
    inherits(CharField, Field)
    

    这种方法有什么好处?

    • 你可以省略任意多个参数 - 如果你只想覆盖一个参数的值,你可以只提供那个参数,而不必显式传递 undefined ,比如说有5个参数而你只想自定义最后一个,就像你建议的其他一些方法一样 .

    • 当使用构造函数函数从一个继承自另一个的对象时,它继承自's easy to accept any arguments which are required by the constructor of the Object you'的构造函数为你做的,如上所述,当 CharField 调用 Field 的构造函数时) .

    • 继承层次结构中的子对象可以根据需要自定义其父构造函数的参数,强制执行它们自己的默认值或确保始终使用某个值 .

  • 2

    如果你广泛使用默认值,这似乎更具可读性:

    function usageExemple(a,b,c,d){
        //defaults
        a=defaultValue(a,1);
        b=defaultValue(b,2);
        c=defaultValue(c,4);
        d=defaultValue(d,8);
    
        var x = a+b+c+d;
        return x;
    }
    

    只需在全局escope上声明此函数即可 .

    function defaultValue(variable,defaultValue){
        return(typeof variable!=='undefined')?(variable):(defaultValue);
    }
    

    使用模式 fruit = defaultValue(fruit,'Apple');

    • PS你可以将 defaultValue 函数重命名为短名称,只是不要使用 default 这是javascript中的保留字 .
  • 2

    我尝试了这里提到的一些选项,并对性能进行了测试 . 在这一刻,逻辑似乎是最快的 . 虽然这是随着时间的推移而变化的主题(不同的JavaScript引擎版本) .

    这些是我的结果(Microsoft Edge 20.10240.16384.0):

    Function executed            Operations/sec     Statistics
    TypeofFunction('test');          92,169,505     ±1.55%   9% slower
    SwitchFuntion('test');            2,904,685     ±2.91%  97% slower
    ObjectFunction({param1: 'test'});   924,753     ±1.71%  99% slower
    LogicalOrFunction('test');      101,205,173     ±0.92%     fastest
    TypeofFunction2('test');         35,636,836     ±0.59%  65% slower
    

    此性能测试可以轻松复制:http://jsperf.com/optional-parameters-typeof-vs-switch/2

    这是测试的代码:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script>
        Benchmark.prototype.setup = function() {
            function TypeofFunction(param1, optParam1, optParam2, optParam3) {
                optParam1 = (typeof optParam1 === "undefined") ? "Some default" : optParam1;
                optParam2 = (typeof optParam2 === "undefined") ? "Another default" : optParam2;
                optParam3 = (typeof optParam3 === "undefined") ? "Some other default" : optParam3;
            }
    
            function TypeofFunction2(param1, optParam1, optParam2, optParam3) {
                optParam1 = defaultValue(optParam1, "Some default");
                optParam2 = defaultValue(optParam2, "Another default");
                optParam3 = defaultValue(optParam3, "Some other default");
            }
    
            function defaultValue(variable, defaultValue) {
                return (typeof variable !== 'undefined') ? (variable) : (defaultValue);
            }
    
            function SwitchFuntion(param1, optParam1, optParam2, optParam3) {
                switch (arguments.length - 1) { // <-- 1 is number of required arguments
                    case 0:
                        optParam1 = 'Some default';
                    case 1:
                        optParam2 = 'Another default';
                    case 2:
                        optParam3 = 'Some other default';
                }
            }
    
            function ObjectFunction(args) {
                var defaults = {
                    optParam1: 'Some default',
                    optParam2: 'Another default',
                    optParam3: 'Some other default'
                }
                args = $.extend({}, defaults, args);
            }
    
            function LogicalOrFunction(param1, optParam1, optParam2, optParam3) {
                optParam1 || (optParam1 = 'Some default');
                optParam2 || (optParam1 = 'Another default');
                optParam3 || (optParam1 = 'Some other default');
            }
        };
    </script>
    
  • 2

    这是我的解决方案 . 有了这个,你可以留下你想要的任何参数 . 可选参数的顺序并不重要,您可以添加自定义验证 .

    function YourFunction(optionalArguments) {
                //var scope = this;
    
                //set the defaults
                var _value1 = 'defaultValue1';
                var _value2 = 'defaultValue2';
                var _value3 = null;
                var _value4 = false;
    
                //check the optional arguments if they are set to override defaults...
                if (typeof optionalArguments !== 'undefined') {
    
                    if (typeof optionalArguments.param1 !== 'undefined')
                        _value1 = optionalArguments.param1;
    
                    if (typeof optionalArguments.param2 !== 'undefined')
                        _value2 = optionalArguments.param2;
    
                    if (typeof optionalArguments.param3 !== 'undefined')
                        _value3 = optionalArguments.param3;
    
                    if (typeof optionalArguments.param4 !== 'undefined')
                        //use custom parameter validation if needed, in this case for javascript boolean
                       _value4 = (optionalArguments.param4 === true || optionalArguments.param4 === 'true');
                }
    
                console.log('value summary of function call:');
                console.log('value1: ' + _value1);
                console.log('value2: ' + _value2);
                console.log('value3: ' + _value3);
                console.log('value4: ' + _value4);
                console.log('');
            }
    
    
            //call your function in any way you want. You can leave parameters. Order is not important. Here some examples:
            YourFunction({
                param1: 'yourGivenValue1',
                param2: 'yourGivenValue2',
                param3: 'yourGivenValue3',
                param4: true,
            });
    
            //order is not important
            YourFunction({
                param4: false,
                param1: 'yourGivenValue1',
                param2: 'yourGivenValue2',
            });
    
            //uses all default values
            YourFunction();
    
            //keeps value4 false, because not a valid value is given
            YourFunction({
                param4: 'not a valid bool'
            });
    
  • 0

    如果我错了,请纠正我,但这似乎是最简单的方法(无论如何,对于一个论点):

    function myFunction(Required,Optional)
    {
        if (arguments.length<2) Optional = "Default";
        //Your code
    }
    
  • 13

    使用ES2015 / ES6,您可以利用 Object.assign ,它可以取代 $.extend()_.defaults()

    function myFunc(requiredArg, options = {}) {
      const defaults = {
        message: 'Hello',
        color: 'red',
        importance: 1
      };
    
      const settings = Object.assign({}, defaults, options);
    
      // do stuff
    }
    

    您也可以使用这样的默认参数

    function myFunc(requiredArg, { message: 'Hello', color: 'red', importance: 1 } = {}) {
      // do stuff
    }
    
  • 1

    那些比运营商版本更短 .

    function foo(a, b) {
        a !== undefined || (a = 'defaultA');
        if(b === undefined) b = 'defaultB';
        ...
    }
    
  • 8

    这似乎是最安全的方式 - 处理所有\ _任何 falsy types 在决定使用 default 之前提供的参数是检查调用函数中是否存在可选参数 .

    依赖于参数对象成员创建,如果缺少参数,甚至不会创建参数成员创建,无论它是否被声明,我们可以像这样编写你的函数:

    function myFunc(requiredArg, optionalArg){
            optionalArg = 1 in arguments ? optionalArg : 'defaultValue';
      //do stuff
      }
    

    利用这种行为:只要我们需要确保函数在其过程中获得某个值,我们就可以安全地检查参数列表中的任何缺失值 .

    在下面的演示代码中,我们将故意将无类型且无值的 undefined 作为默认值,以确定它是否可能在伪造的参数值上失败,例如0 false等,或者它是否按预期运行 .

    function argCheck( arg1, arg2, arg3 ){
    
           arg1 = 0 in arguments || undefined;
           arg2 = 1 in arguments || false;
           arg3 = 2 in arguments || 0;
       var arg4 = 3 in arguments || null;
    
       console.log( arg1, arg2, arg3, arg4 ) 
    }
    

    现在,检查几个有 Value 的参数值,看看它们的存在是否被正确检测到,因此评估为 true

    argCheck( "", 0, false, null );
    >> true true true true
    

    这意味着 - 他们没有做错 .

    argCheck( );
    >> undefined false 0 null
    

    正如我们所看到的,参数arg1,arg2,arg3和未声明的arg4正在按顺序返回它们的确切 default 值 . 因为我们现在已经确定它有效,所以我们可以通过使用: if 或三元条件来重写实际上能够使用它们的函数,如第一个例子中所示 .

    对于具有多个可选参数的函数, - 循环,可能为我们节省了一些位 . 但是由于参数 names 以编程方式编写了一个默认值,我们只能通过参数[index]来访问它们,这些无用的代码可读性明智 .

    但是除了这种在某些编码情况下可能完全可以接受的不便之外,还存在多个和任意数量的参数默认值的另一个无法解决的问题 . 这可能并且应该被视为一个错误,因为我们不能再跳过参数,因为我们曾经可以在不给出值的情况下使用以下语法:

    argCheck("a",,22,{});
    

    因为它会扔!这使我们无法用我们所需的默认值的特定假类型替换我们的参数 . 这是愚蠢的,因为arguments对象是一个类似于数组的对象,并且应该原生或默认支持这种语法和约定!

    由于这个短视的决定,我们不能再希望编写这样的函数:

    function argCheck( ) {
        var _default = [undefined, 0, false, null ],
            _arg = arguments;
    
     for( var x in _default ) {
             x in _arg ? 1 : _arg[x] = _default[x];
            }
        console.log( _arg[0],_arg[1],_arg[2],_arg[3] );
    }
    

    在这种情况下,我们可以在参数行中编写所需类型的每个默认值,并且至少能够通过args.index访问它们 .

    例如,此函数调用将产生:

    argCheck();
    >>undefined 0 false null
    

    在我们的默认参数值数组中定义 . 但是仍然可以使用以下内容:

    argCheck({})
    >>Object {  } 0 false null
    
    argCheck({}, [])
    >>Object {  } Array [  ] false null
    

    但遗憾的是没有:

    argCheck("a",,,22);
     >>SyntaxError: expected expression, got ','
    

    否则将记录:

    >>a 0 false 22
    

    但那是一个更美好的世界!但是 - 对于原始问题 - 最顶层的功能会很好 . 例如 . :

    function argCheck( arg, opt ) {
             1 in arguments ? 1 : opt = "default";
             console.log( arg, opt );
    }
    

    p.s:抱歉在写入时不保留参数输入中所选默认值的类型 .

相关问题