Function overloading in Javascript - Best practices

后端 未结 30 1522
难免孤独
难免孤独 2020-11-22 03:33

What is the best way(s) to fake function overloading in Javascript?

I know it is not possible to overload functions in Javascript as in other languages. If I neede

相关标签:
30条回答
  • 2020-11-22 04:04

    Since JavaScript doesn't have function overload options object can be used instead. If there are one or two required arguments, it's better to keep them separate from the options object. Here is an example on how to use options object and populated values to default value in case if value was not passed in options object.

        function optionsObjectTest(x, y, opts) {
            opts = opts || {}; // default to an empty options object
    
            var stringValue = opts.stringValue || "string default value";
            var boolValue = !!opts.boolValue; // coerces value to boolean with a double negation pattern
            var numericValue = opts.numericValue === undefined ? 123 : opts.numericValue;
    
            return "{x:" + x + ", y:" + y + ", stringValue:'" + stringValue + "', boolValue:" + boolValue + ", numericValue:" + numericValue + "}";
    
    }
    

    here is an example on how to use options object

    0 讨论(0)
  • 2020-11-22 04:04

    The first option really deserves attention cause it's the thing I've come up in quite complex code setup. So, my answer is

    1. Using different names in the first place

    With a little but essential hint, names should look different for computer, but not for you. Name overloaded functions like: func, func1, func2.

    0 讨论(0)
  • 2020-11-22 04:05

    I often do this:

    C#:

    public string CatStrings(string p1)                  {return p1;}
    public string CatStrings(string p1, int p2)          {return p1+p2.ToString();}
    public string CatStrings(string p1, int p2, bool p3) {return p1+p2.ToString()+p3.ToString();}
    
    CatStrings("one");        // result = one
    CatStrings("one",2);      // result = one2
    CatStrings("one",2,true); // result = one2true
    

    JavaScript Equivalent:

    function CatStrings(p1, p2, p3)
    {
      var s = p1;
      if(typeof p2 !== "undefined") {s += p2;}
      if(typeof p3 !== "undefined") {s += p3;}
      return s;
    };
    
    CatStrings("one");        // result = one
    CatStrings("one",2);      // result = one2
    CatStrings("one",2,true); // result = one2true
    

    This particular example is actually more elegant in javascript than C#. Parameters which are not specified are 'undefined' in javascript, which evaluates to false in an if statement. However, the function definition does not convey the information that p2 and p3 are optional. If you need a lot of overloading, jQuery has decided to use an object as the parameter, for example, jQuery.ajax(options). I agree with them that this is the most powerful and clearly documentable approach to overloading, but I rarely need more than one or two quick optional parameters.

    EDIT: changed IF test per Ian's suggestion

    0 讨论(0)
  • 2020-11-22 04:06

    You can now do function overloading in ECMAScript 2018 without polyfills, checking var length/type, etc., just use the spread syntax.

    function foo(var1, var2, opts){
      // set default values for parameters
      const defaultOpts = {
        a: [1,2,3],
        b: true,
        c: 0.3289,
        d: "str",
      }
      // merge default and passed-in parameters
      // defaultOpts must go first!
      const mergedOpts = {...defaultOpts, ...opts};
    
      // you can now refer to parameters like b as mergedOpts.b,
      // or just assign mergedOpts.b to b
      console.log(mergedOpts.a);
      console.log(mergedOpts.b);
      console.log(mergedOpts.c);  
      console.log(mergedOpts.d);
    }
    // the parameters you passed in override the default ones
    // all JS types are supported: primitives, objects, arrays, functions, etc.
    let var1, var2="random var";
    foo(var1, var2, {a: [1,2], d: "differentString"});
    
    // parameter values inside foo:
    //a: [1,2]
    //b: true
    //c: 0.3289
    //d: "differentString"

    What is spread syntax?

    The Rest/Spread Properties for ECMAScript proposal (stage 4) adds spread properties to object literals. It copies own enumerable properties from a provided object onto a new object. More on mdn

    Note: spread syntax in object literals doesn't work in Edge and IE and it is an experimental feature. see browser compatability

    0 讨论(0)
  • 2020-11-22 04:06

    As of July 2017, the following has been the common technique. Note that we can also perform type checking within the function.

    function f(...rest){   // rest is an array
       console.log(rest.length);
       for (v of rest) if (typeof(v)=="number")console.log(v);
    }
    f(1,2,3);  // 3 1 2 3
    
    0 讨论(0)
  • 2020-11-22 04:10

    The best way to do function overloading with parameters is not to check the argument length or the types; checking the types will just make your code slow and you have the fun of Arrays, nulls, Objects, etc.

    What most developers do is tack on an object as the last argument to their methods. This object can hold anything.

    function foo(a, b, opts) {
      // ...
      if (opts['test']) { } //if test param exists, do something.. 
    }
    
    
    foo(1, 2, {"method":"add"});
    foo(3, 4, {"test":"equals", "bar":"tree"});
    

    Then you can handle it anyway you want in your method. [Switch, if-else, etc.]

    0 讨论(0)
提交回复
热议问题