【问题标题】:Javascript - function with optional parameters as object?Javascript - 以可选参数作为对象的函数?
【发布时间】:2015-02-28 09:54:28
【问题描述】:

我需要一个函数,它的参数是一个对象,如果我把它留空,它将加载默认值。

类似:

function loadMap(args) { //args is an object and its optional

   //this is what I want to do, test args and load defauts if necesary
   /*
   pseudocode:
   if args.latitude is not set then
       give it a default value

   if args.longitude is not set then
       give it a default value

    end pseudocode */

   alert("Latitude is "+args.latitude );
   alert("Longitude is "+args.longitude );
}

//outputs the default values
loadMap();

//outputs custom values
loadMap({latitude: "x.xxxx", longitude: "-x.xxxx"});

//and should work too and output one default and one custom value
loadMap({latitude: "x.xxxx"});

我在这个问题 (Is there a better way to do optional function parameters in Javascript?) 中找到了这个解决方案,但它需要 jQuery: http://jsfiddle.net/xy84kwdv/

这几乎是我想要的,但我不想依赖 jquery 函数。

【问题讨论】:

    标签: javascript object parameters optional


    【解决方案1】:

    这个问题现在肯定已经超过3年了(2018-03-02)。我搜索了这个主题,但我得到的大多数问题和排名靠前的答案似乎都已经过时了,比如thisthisthisthis

    目前,lots of browsers 支持ES6/ECMAScript 2015(ECMAScript 第 6 版)。为了兼容性,你可以使用WebpackJs(或其他打包器)和BabelJs(或其他编译器)来编译和打包你的ES6代码到ES5。而这个问题的 ES6 版本答案可能是Object Destructuring

    function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
        console.log(size, cords, radius);
        // do some chart drawing
    }
    
    drawES2015Chart({cords: {x: 18, y: 30}, radius: 30});
    
    function fn(requiredArg, {optionalArg = 'Default Value', a = 1, b ={some: 'object'}} = {}){
        // Do with destructured values: requiredArg, optionalArg, a, and b.
        console.log(requiredArg, optionalArg, a, b);
    }
    

    所以对于你的问题,它将是:

    function loadMap({latitude = "x.xxxx", longitude = "-x.xxxx"} = {}) {
        console.log('latitude is:', latitude, 'and longitude is:', longitude);
        console.log(`latitude is: ${latitude}, and longitude is: ${longitude}`);
    }
    
    // Call the function.
    loadMap({latitude: "1.2345", longitude: "-6.7890"});
    

    【讨论】:

    • 甜蜜!谢谢!从您发布的 MDN 链接中:我想知道为什么我需要右侧的空 {}。根据文档:You could have also written the function without the right-hand side assignment. However, if you leave out the right-hand side assignment, the function will look for at least one argument to be supplied when invoked, whereas in its current form, you can simply call drawES2015Chart() without supplying any parameters
    【解决方案2】:

    您是否正在寻找类似的东西:

    function loadMap(args) { 
        args = args || {}; 
        args.latitude = args.latitude || "X.XXX"; 
        args.longitude = args.longitude || "Y.YYY"; 
        alert(args.latitude);
        alert(args.longitude);
    }; 
    
    loadMap({latitude:"custom_latitude"});
    

    【讨论】:

    • jsfiddle.net/f5nqnwc1 - 如您所见,如果您只传递一个自定义值并将其余部分留空,则其行为将无法达到预期
    • 我测试过了。而且它工作得很好......代码很干净,没有什么比其他 10000 种算法更复杂的实现相同......你的解决方案是迄今为止最好的!
    • 这会搞砸loadMap({latitude: 0})
    • 啊是的...我们说的是 0 就像 FALSE...没关系,我们可以解决
    • 没关系...没有什么我不能用一些三元运算解决的!
    【解决方案3】:

    这使得参数对象成为可选的,以及使单个属性成为可选的:

    var defaults = { latitude: x, longitude: y };
    function loadMap(args) {
        args = args || {};
        for (var key in defaults) {
            if (!(key in args)) {
                args[key] = default[key];
            }
        }
        ...
    }
    

    【讨论】:

    • 我添加了一条评论,但我没有很好地阅读您的答案...这似乎也有效,而且很干净
    【解决方案4】:

    使用“??”而不是“||”或者您可能在未定义或错误的变量中有错误

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

    function loadMap(args) { 
        args = args ?? {}; 
        args.latitude = args.latitude ?? "X.XXX"; 
        args.longitude = args.longitude ?? "Y.YYY"; 
        alert(args.latitude);
        alert(args.longitude);
    }; 
    
    loadMap({latitude:"custom_latitude"});
    

    【讨论】:

      【解决方案5】:

      How to overload functions in javascript? 查看OP的第二个答案。它提供了使用 jQ 的替代方法。

      注意:如果 args 通过但计算结果为 true,Kim 的代码将导致逻辑​​错误。 更好的修复: optionalArg = (typeof optionalArg === "未定义") ? "defaultValue" : 可选参数;

      【讨论】:

      • 不要发布仅链接的答案。将问题标记为重复问题。
      【解决方案6】:

      矫枉过正,引入完整的对象克隆(ECMAScript 5.1)

      function cloneOwnProperties(A, B, overwrite) { // this is shallow
          var i, p;
          if (!(A instanceof Object)) {
              if (undefined === A) A = {};
              else throw new TypeError('cloneOwnProperties called on non-object');
          }
          if (!B) B = {};
          p = Object.getOwnPropertyNames(A);
          for (i = 0; i < p.length; ++i)
              if (overwrite || !(p[i] in B))
                  Object.defineProperty(B, p[i], Object.getOwnPropertyDescriptor(A, p[i]));
          return B;
      }
      
      // and for completeness
      function cloneObject(obj_in, clone_seal, clone_frozen) {
          var obj_out;
          if (!(obj_in instanceof Object))
              throw new TypeError('cloneObject called on non-object');
          obj_out = Object.create(Object.getPrototypeOf(obj_in));
          cloneOwnProperties(obj_in, obj_out, true);
          if (clone_seal && Object.isSealed(obj_in)) Object.seal(obj_out);
          if (clone_frozen && Object.isFrozen(obj_in)) Object.freeze(obj_out);
          return obj_out;
      }
      // back on topic
      

      现在您可以使用它来设置一些默认值

      function foo(bar) {
          bar = cloneOwnProperties(bar, {
              fizz: true,
              buzz: false
          }, true);
          return bar;
      }
      
      foo({buzz: 'user_value'}); // {fizz: true, buzz: "user_value"}
      

      【讨论】:

        【解决方案7】:

        Fisher 的答案应该是公认的答案。此外,如果您想重命名任何解构变量同时仍保持默认值,您可以这样做:

        function findByCoordinates({coordinates: cords = {x: 0, y: 0}} = {}) {
          console.log(cords);
          // Some calculation...
        }
        

        【讨论】:

          猜你喜欢
          • 2011-06-23
          • 2013-11-02
          • 1970-01-01
          • 2013-03-20
          • 2018-02-23
          • 2012-05-30
          • 1970-01-01
          • 2011-11-25
          相关资源
          最近更新 更多