Wie überlade ich Funktionen in Javascript?

102

Klassischer (Nicht-js) Ansatz zur Überladung:

function myFunc(){
 //code
}

function myFunc(overloaded){
 //other code
}

In Javascript können nicht mehr als eine Funktion mit demselben Namen definiert werden. Als solche zeigen sich solche Dinge:

function myFunc(options){
 if(options["overloaded"]){
  //code
 }
}

Gibt es eine bessere Problemumgehung für das Überladen von Funktionen in Javascript als das Übergeben eines Objekts mit den darin enthaltenen Überladungen?

Das Übergeben von Überladungen kann schnell dazu führen, dass eine Funktion zu ausführlich wird, da für jede mögliche Überladung eine bedingte Anweisung erforderlich wäre. Die Verwendung von Funktionen zum Erreichen des //codeInneren dieser bedingten Anweisungen kann zu schwierigen Situationen mit Gültigkeitsbereichen führen.

Travis J.
quelle
1
Dann denken Sie über falsches Javascript nach; Wenn Sie Probleme mit Überladungen und Umfang haben, sollten Sie wahrscheinlich einen anderen Methodennamen haben, da es so klingt, als würde es einen anderen Job machen
Joshcomley
@joshcomley - Für Überladungen und den Umfang ist Code erforderlich. Ich versuche nur sicherzustellen, dass der von mir verwendete Code so effizient wie möglich ist. Der Umgang mit Bereichen mit Problemumgehungen ist in Ordnung, aber ich ziehe es vor, zumindest Best-Practice-Methoden zu verwenden.
Travis J
2
Mögliches Duplikat der Funktionsüberladung in Javascript - Best Practices
cdeszaq

Antworten:

126

Das Überladen von Argumenten in Javascript hat mehrere Aspekte:

  1. Variable Argumente - Sie können verschiedene Sätze von Argumenten (sowohl in Typ als auch in Menge) übergeben, und die Funktion verhält sich so, dass sie mit den an sie übergebenen Argumenten übereinstimmt.

  2. Standardargumente - Sie können einen Standardwert für ein Argument definieren, wenn es nicht übergeben wird.

  3. Benannte Argumente - Die Reihenfolge der Argumente spielt keine Rolle mehr und Sie benennen nur, welche Argumente Sie an die Funktion übergeben möchten.

Unten finden Sie einen Abschnitt zu jeder dieser Kategorien der Argumentbehandlung.

Variable Argumente

Da in Javascript keine Typprüfung für Argumente oder die erforderliche Anzahl von Argumenten vorhanden ist, können Sie nur eine Implementierung verwenden myFunc(), die sich an die an sie übergebenen Argumente anpassen kann, indem Sie den Typ, das Vorhandensein oder die Anzahl der Argumente überprüfen.

jQuery macht das die ganze Zeit. Sie können einige der Argumente optional machen oder in Ihrer Funktion verzweigen, je nachdem, welche Argumente an sie übergeben werden.

Bei der Implementierung dieser Arten von Überlastungen stehen Ihnen verschiedene Techniken zur Verfügung:

  1. Sie können das Vorhandensein eines bestimmten Arguments überprüfen, indem Sie überprüfen, ob der deklarierte Argumentname Wert ist undefined.
  2. Sie können die Gesamtmenge oder Argumente mit überprüfen arguments.length.
  3. Sie können den Typ eines bestimmten Arguments überprüfen.
  4. Für eine variable Anzahl von Argumenten können Sie das argumentsPseudo-Array verwenden, um auf ein bestimmtes Argument mit zuzugreifen arguments[i].

Hier sind einige Beispiele:

Schauen wir uns die obj.data()Methode von jQuery an . Es werden vier verschiedene Nutzungsformen unterstützt:

obj.data("key");
obj.data("key", value);
obj.data();
obj.data(object);

Jeder löst ein anderes Verhalten aus und würde ohne diese dynamische Form der Überladung vier separate Funktionen erfordern.

So kann man zwischen all diesen Optionen auf Englisch unterscheiden und sie dann alle im Code kombinieren:

// get the data element associated with a particular key value
obj.data("key");

Wenn das erste übergebene Argument .data()eine Zeichenfolge ist und das zweite Argument undefined, muss der Aufrufer dieses Formular verwenden.


// set the value associated with a particular key
obj.data("key", value);

Wenn das zweite Argument nicht undefiniert ist, legen Sie den Wert eines bestimmten Schlüssels fest.


// get all keys/values
obj.data();

Wenn keine Argumente übergeben werden, geben Sie alle Schlüssel / Werte in einem zurückgegebenen Objekt zurück.


// set all keys/values from the passed in object
obj.data(object);

Wenn der Typ des ersten Arguments ein einfaches Objekt ist, legen Sie alle Schlüssel / Werte von diesem Objekt fest.


So können Sie all diese Elemente in einem Satz Javascript-Logik kombinieren:

 // method declaration for .data()
 data: function(key, value) {
     if (arguments.length === 0) {
         // .data()
         // no args passed, return all keys/values in an object
     } else if (typeof key === "string") {
         // first arg is a string, look at type of second arg
         if (typeof value !== "undefined") {
             // .data("key", value)
             // set the value for a particular key
         } else {
             // .data("key")
             // retrieve a value for a key
         }
     } else if (typeof key === "object") {
         // .data(object)
         // set all key/value pairs from this object
     } else {
         // unsupported arguments passed
     }
 },

Der Schlüssel zu dieser Technik besteht darin, sicherzustellen, dass alle Arten von Argumenten, die Sie akzeptieren möchten, eindeutig identifizierbar sind und es keine Verwirrung darüber gibt, welche Form der Anrufer verwendet. Dies erfordert im Allgemeinen die richtige Reihenfolge der Argumente und die Sicherstellung, dass Typ und Position der Argumente so eindeutig sind, dass Sie immer erkennen können, welches Formular verwendet wird.

Wenn Sie beispielsweise eine Funktion haben, die drei Zeichenfolgenargumente akzeptiert:

obj.query("firstArg", "secondArg", "thirdArg");

Sie können das dritte Argument leicht optional machen und diese Bedingung leicht erkennen, aber Sie können nicht nur das zweite Argument optional machen, da Sie nicht sagen können, welches dieser Argumente der Anrufer übergeben soll, da es keine Möglichkeit gibt, festzustellen, ob das zweite Argument vorliegt Das Argument soll das zweite Argument sein, oder das zweite Argument wurde weggelassen. Was also an der Stelle des zweiten Arguments steht, ist tatsächlich das dritte Argument:

obj.query("firstArg", "secondArg");
obj.query("firstArg", "thirdArg");

Da alle drei Argumente vom gleichen Typ sind, können Sie den Unterschied zwischen verschiedenen Argumenten nicht erkennen, sodass Sie nicht wissen, was der Aufrufer beabsichtigt hat. Bei diesem Aufrufstil kann nur das dritte Argument optional sein. Wenn Sie das zweite Argument weglassen möchten, muss es stattdessen als null(oder ein anderer erkennbarer Wert) übergeben werden, und Ihr Code erkennt Folgendes:

obj.query("firstArg", null, "thirdArg");

Hier ist ein jQuery-Beispiel für optionale Argumente. Beide Argumente sind optional und nehmen Standardwerte an, wenn sie nicht übergeben werden:

clone: function( dataAndEvents, deepDataAndEvents ) {
    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

    return this.map( function () {
        return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
    });
},

Hier ist ein jQuery-Beispiel, bei dem das Argument fehlen kann oder einer von drei verschiedenen Typen, wodurch Sie vier verschiedene Überladungen erhalten:

html: function( value ) {
    if ( value === undefined ) {
        return this[0] && this[0].nodeType === 1 ?
            this[0].innerHTML.replace(rinlinejQuery, "") :
            null;

    // See if we can take a shortcut and just use innerHTML
    } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {

        value = value.replace(rxhtmlTag, "<$1></$2>");

        try {
            for ( var i = 0, l = this.length; i < l; i++ ) {
                // Remove element nodes and prevent memory leaks
                if ( this[i].nodeType === 1 ) {
                    jQuery.cleanData( this[i].getElementsByTagName("*") );
                    this[i].innerHTML = value;
                }
            }

        // If using innerHTML throws an exception, use the fallback method
        } catch(e) {
            this.empty().append( value );
        }

    } else if ( jQuery.isFunction( value ) ) {
        this.each(function(i){
            var self = jQuery( this );

            self.html( value.call(this, i, self.html()) );
        });

    } else {
        this.empty().append( value );
    }

    return this;
},

Benannte Argumente

In anderen Sprachen (wie Python) können benannte Argumente übergeben werden, um nur einige Argumente zu übergeben und die Argumente unabhängig von der Reihenfolge zu machen, in der sie übergeben werden. Javascript unterstützt die Funktion benannter Argumente nicht direkt. Ein Entwurfsmuster, das üblicherweise an seiner Stelle verwendet wird, besteht darin, eine Karte mit Eigenschaften / Werten zu übergeben. Dies kann durch Übergeben eines Objekts mit Eigenschaften und Werten erfolgen. In ES6 und höher können Sie tatsächlich ein Map-Objekt selbst übergeben.

Hier ist ein einfaches ES5-Beispiel:

jQuery's $.ajax() akzeptiert eine Verwendungsform, bei der Sie nur einen einzelnen Parameter übergeben, bei dem es sich um ein reguläres Javascript-Objekt mit Eigenschaften und Werten handelt. Welche Eigenschaften Sie übergeben, bestimmt, welche Argumente / Optionen an den Ajax-Aufruf übergeben werden. Einige können erforderlich sein, viele sind optional. Da es sich um Eigenschaften eines Objekts handelt, gibt es keine bestimmte Reihenfolge. Tatsächlich gibt es mehr als 30 verschiedene Eigenschaften, die an dieses Objekt übergeben werden können. Es ist nur eine (die URL) erforderlich.

Hier ist ein Beispiel:

$.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
    // process result here
});

Innerhalb der $.ajax()Implementierung kann es dann einfach abfragen, welche Eigenschaften an das eingehende Objekt übergeben wurden, und diese als benannte Argumente verwenden. Dies kann entweder mit for (prop in obj)oder durch Abrufen aller Eigenschaften in einem Array mit Object.keys(obj)und anschließendes Iterieren dieses Arrays erfolgen.

Diese Technik wird in Javascript sehr häufig verwendet, wenn eine große Anzahl von Argumenten vorhanden ist und / oder viele Argumente optional sind. Hinweis: Dies stellt eine Belastung für die Implementierungsfunktion dar, um sicherzustellen, dass ein minimal gültiger Satz von Argumenten vorhanden ist, und um dem Aufrufer ein Debug-Feedback zu geben, was fehlt, wenn nicht genügend Argumente übergeben werden (wahrscheinlich durch Auslösen einer Ausnahme mit einer hilfreichen Fehlermeldung). .

In einer ES6-Umgebung ist es möglich, mithilfe der Destrukturierung Standardeigenschaften / -werte für das oben übergebene Objekt zu erstellen. Dies wird in diesem Referenzartikel ausführlicher erläutert .

Hier ist ein Beispiel aus diesem Artikel:

function selectEntries({ start=0, end=-1, step=1 } = {}) {
    ···
};

Dies schafft Standardeigenschaften und Werte für die start, endund stepEigenschaften auf ein Objekt auf den übergebenenselectEntries() Funktion.

Standardwerte für Funktionsargumente

In ES6 fügt Javascript eine integrierte Sprachunterstützung für Standardwerte für Argumente hinzu.

Beispielsweise:

function multiply(a, b = 1) {
  return a*b;
}

multiply(5); // 5

Weitere Beschreibung der Möglichkeiten, wie dies hier auf MDN verwendet werden kann .

jfriend00
quelle
Also sollte ich mich einfach an eine anpassbare Funktion halten und diese als Best Practice für die Implementierung der Funktionsüberlastungsfassade akzeptieren?
Travis J
2
@TravisJ - Ja, anpassbare Funktion ist die Art und Weise, wie Überladungen in Javascript durchgeführt werden. Sie können auch eine separat benannte Funktion mit unterschiedlichen Argumenten verwenden. Wenn die beiden Implementierungen nichts gemeinsam haben, ist beides eine akzeptable Praxis. Wenn die beiden Implementierungen im Wesentlichen dasselbe tun, aber nur mit unterschiedlichen Argumenten beginnen, wird Ihre Benutzeroberfläche meiner Meinung nach kompakter, wenn Sie die anpassbare Funktion verwenden, und Sie haben die Möglichkeit, Code zwischen den beiden verwandten Implementierungen auszutauschen.
jfriend00
Es wurden einige Codebeispiele hinzugefügt, die sowohl in Englisch als auch im tatsächlichen Code erklärt wurden.
jfriend00
Ich erhalte einen Fehler, ein unerwartetes Token '=' in der neuesten Version von Safari, wenn ich dies versuche resetProgressBar: function(display_errors, lockout = false).
Nick
@Nick - Gemäß dieser ES6-Kompatibilitätstabelle sollten Standardparameterwerte in Safari 10 und höher funktionieren. Auf dieser MDN-Seite wird in Safari "keine Unterstützung" angezeigt. Ich habe keinen Mac und kann ihn daher nicht selbst testen. Es scheint im Allgemeinen eine der später implementierten ES6-Funktionen in vielen Browsern zu sein. Zum Beispiel sieht es noch nicht so aus, als wäre es in iOS9.
jfriend00
33

Das Überladen einer Funktion in JavaScript kann auf viele Arten erfolgen. Alle von ihnen beinhalten eine einzelne Master-Funktion, die entweder alle Prozesse ausführt oder an Unterfunktionen / Prozesse delegiert.

Eine der häufigsten einfachen Techniken beinhaltet einen einfachen Wechsel:

function foo(a, b) {
    switch (arguments.length) {
    case 0:
        //do basic code
        break;
    case 1:
        //do code with `a`
        break;
    case 2:
    default:
        //do code with `a` & `b`
        break;
    }
}

Eine elegantere Technik wäre die Verwendung eines Arrays (oder Objekts, wenn Sie nicht bei jeder Argumentanzahl Überladungen vornehmen ):

fooArr = [
    function () {
    },
    function (a) {
    },
    function (a,b) {
    }
];
function foo(a, b) {
    return fooArr[arguments.length](a, b);
}

Das vorherige Beispiel ist nicht sehr elegant, jeder kann es ändern fooArr, und es würde fehlschlagen, wenn jemand mehr als zwei Argumente an übergibt. fooEine bessere Form wäre daher, ein Modulmuster und einige Überprüfungen zu verwenden:

var foo = (function () {
    var fns;
    fns = [
        function () {
        },
        function (a) {
        },
        function (a, b) {
        }
    ];
    function foo(a, b) {
        var fnIndex;
        fnIndex = arguments.length;
        if (fnIndex > foo.length) {
            fnIndex = foo.length;
        }
        return fns[fnIndex].call(this, a, b);
    }
    return foo;
}());

Natürlich möchten Ihre Überladungen möglicherweise eine dynamische Anzahl von Parametern verwenden, sodass Sie ein Objekt für die fnsSammlung verwenden können.

var foo = (function () {
    var fns;
    fns = {};
    fns[0] = function () {
    };
    fns[1] = function (a) {
    };
    fns[2] = function (a, b) {
    };
    fns.params = function (a, b /*, params */) {
    };
    function foo(a, b) {
        var fnIndex;
        fnIndex = arguments.length;
        if (fnIndex > foo.length) {
            fnIndex = 'params';
        }
        return fns[fnIndex].apply(this, Array.prototype.slice.call(arguments));
    }
    return foo;
}());

Meine persönliche Präferenz ist in der Regel die switch, obwohl sie die Master-Funktion erweitert. Ein häufiges Beispiel dafür, wo ich diese Technik verwenden würde, wäre eine Accessor / Mutator-Methode:

function Foo() {} //constructor
Foo.prototype = {
    bar: function (val) {
        switch (arguments.length) {
        case 0:
            return this._bar;
        case 1:
            this._bar = val;
            return this;
        }
    }
}
zzzzBov
quelle
Dies ist ein schönes Beispiel für eine Alternative :)
Travis J
1
Schön, ich mag diese 2. Technik
Nick Rolando
8

Sie können keine Methodenüberladung im engeren Sinne durchführen. Nicht so, wie es in javaoder unterstützt wird c#.

Das Problem ist, dass JavaScript das Überladen von Methoden NICHT nativ unterstützt. Wenn also zwei oder mehr Funktionen mit demselben Namen angezeigt / analysiert werden, wird nur die zuletzt definierte Funktion berücksichtigt und die vorherigen überschrieben.

Eine der Möglichkeiten, die meiner Meinung nach für den größten Teil des Falls geeignet sind, ist folgende:

Nehmen wir an, Sie haben eine Methode

function foo(x)
{
} 

Anstatt eine Methode zu überladen, die in Javascript nicht möglich ist, können Sie eine neue Methode definieren

fooNew(x,y,z)
{
}

und ändern Sie dann die 1. Funktion wie folgt -

function foo(x)
{
  if(arguments.length==2)
  {
     return fooNew(arguments[0],  arguments[1]);
  }
} 

Wenn Sie viele solcher überladenen Methoden haben, sollten Sie switchnicht nur if-elseAnweisungen verwenden.

( weitere Details ) PS: Der obige Link führt zu meinem persönlichen Blog, der zusätzliche Details dazu enthält.

Aniket Thakur
quelle
Das ist kein Problem, das ist eine Funktion.
Inetphantom
4

Ich verwende einen etwas anderen Überladungsansatz basierend auf der Argumentnummer. Ich glaube jedoch, dass John Fawcetts Ansatz auch gut ist. Hier das Beispiel, Code basierend auf den Erklärungen von John Resig (jQuery's Author).

// o = existing object, n = function name, f = function.
    function overload(o, n, f){
        var old = o[n];
        o[n] = function(){
            if(f.length == arguments.length){
                return f.apply(this, arguments);
            }
            else if(typeof o == 'function'){
                return old.apply(this, arguments);
            }
        };
    }

Benutzerfreundlichkeit:

var obj = {};
overload(obj, 'function_name', function(){ /* what we will do if no args passed? */});
overload(obj, 'function_name', function(first){ /* what we will do if 1 arg passed? */});
overload(obj, 'function_name', function(first, second){ /* what we will do if 2 args passed? */});
overload(obj, 'function_name', function(first,second,third){ /* what we will do if 3 args passed? */});
//... etc :)
Valentin Rusk
quelle
4

In Javascript können Sie die Funktion nur einmal implementieren und die Funktion ohne die Parameter aufrufen. myFunc() Anschließend prüfen Sie, ob die Optionen "undefiniert" sind.

function myFunc(options){
 if(typeof options != 'undefined'){
  //code
 }
}
Murtnowski
quelle
3

Ich habe versucht, eine elegante Lösung für dieses hier beschriebene Problem zu entwickeln . Und die Demo finden Sie hier . Die Verwendung sieht folgendermaßen aus:

var out = def({
    'int': function(a) {
        alert('Here is int '+a);
    },

    'float': function(a) {
        alert('Here is float '+a);
    },

    'string': function(a) {
        alert('Here is string '+a);
    },

    'int,string': function(a, b) {
        alert('Here is an int '+a+' and a string '+b);
    },
    'default': function(obj) {
        alert('Here is some other value '+ obj);
    }

});

out('ten');
out(1);
out(2, 'robot');
out(2.5);
out(true);

Die Methoden, um dies zu erreichen:

var def = function(functions, parent) {
 return function() {
    var types = [];
    var args = [];
    eachArg(arguments, function(i, elem) {
        args.push(elem);
        types.push(whatis(elem));
    });
    if(functions.hasOwnProperty(types.join())) {
        return functions[types.join()].apply(parent, args);
    } else {
        if (typeof functions === 'function')
            return functions.apply(parent, args);
        if (functions.hasOwnProperty('default'))
            return functions['default'].apply(parent, args);        
    }
  };
};

var eachArg = function(args, fn) {
 var i = 0;
 while (args.hasOwnProperty(i)) {
    if(fn !== undefined)
        fn(i, args[i]);
    i++;
 }
 return i-1;
};

var whatis = function(val) {

 if(val === undefined)
    return 'undefined';
 if(val === null)
    return 'null';

 var type = typeof val;

 if(type === 'object') {
    if(val.hasOwnProperty('length') && val.hasOwnProperty('push'))
        return 'array';
    if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString'))
        return 'date';
    if(val.hasOwnProperty('toExponential'))
        type = 'number';
    if(val.hasOwnProperty('substring') && val.hasOwnProperty('length'))
        return 'string';
 }

 if(type === 'number') {
    if(val.toString().indexOf('.') > 0)
        return 'float';
    else
        return 'int';
 }

 return type;
};
stamat
quelle
1
Eine Funktion zur Handhabung der Eingaben, sehr clever.
Travis J
3

https://github.com/jrf0110/leFunc

var getItems = leFunc({
  "string": function(id){
    // Do something
  },
  "string,object": function(id, options){
    // Do something else
  },
  "string,object,function": function(id, options, callback){
    // Do something different
    callback();
  },
  "object,string,function": function(options, message, callback){
    // Do something ca-raaaaazzzy
    callback();
  }
});

getItems("123abc"); // Calls the first function - "string"
getItems("123abc", {poop: true}); // Calls the second function - "string,object"
getItems("123abc", {butt: true}, function(){}); // Calls the third function - "string,object,function"
getItems({butt: true}, "What what?" function(){}); // Calls the fourth function - "object,string,function"
John Fawcett
quelle
3

Kein Problem mit Überladung in JS. Wie kann man beim Überladen einen sauberen Code pflegen?

Sie können eine Weiterleitung verwenden , um sauberen Code zu erhalten, basierend auf zwei Dingen:

  1. Anzahl der Argumente (beim Aufruf der Funktion).
  2. Art der Argumente (beim Aufruf der Funktion)

      function myFunc(){
          return window['myFunc_'+arguments.length+Array.from(arguments).map((arg)=>typeof arg).join('_')](...arguments);
       }
    
        /** one argument & this argument is string */
      function myFunc_1_string(){
    
      }
       //------------
       /** one argument & this argument is object */
      function myFunc_1_object(){
    
      }
      //----------
      /** two arguments & those arguments are both string */
      function myFunc_2_string_string(){
    
      }
       //--------
      /** Three arguments & those arguments are : id(number),name(string), callback(function) */
      function myFunc_3_number_string_function(){
                let args=arguments;
                  new Person(args[0],args[1]).onReady(args[3]);
      }
    
       //--- And so on ....   
Abdennour TOUMI
quelle
2

Da JavaScript keine Funktionsüberladungsoptionen hat , kann stattdessen ein Objekt verwendet werden. Wenn ein oder zwei Argumente erforderlich sind, ist es besser, sie vom Optionsobjekt zu trennen. Hier ist ein Beispiel für die Verwendung des Optionsobjekts und der aufgefüllten Werte als Standardwert, falls im Optionsobjekt kein Wert übergeben wurde.

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

}}

Hier ist ein Beispiel für die Verwendung des Optionsobjekts

Vlad Bezden
quelle
2

Dazu müssen Sie eine Funktion erstellen, die die Funktion einem Objekt hinzufügt. Diese wird dann abhängig von der Anzahl der Argumente ausgeführt, die Sie an die Funktion senden:

<script > 
//Main function to add the methods
function addMethod(object, name, fn) {
  var old = object[name];
  object[name] = function(){
    if (fn.length == arguments.length)
      return fn.apply(this, arguments)
    else if (typeof old == 'function')
      return old.apply(this, arguments);
  };
}


  var ninjas = {
   values: ["Dean Edwards", "Sam Stephenson", "Alex Russell"]
};

//Here we declare the first function with no arguments passed
  addMethod(ninjas, "find", function(){
    return this.values;
});

//Second function with one argument
  addMethod(ninjas, "find", function(name){
    var ret = [];
    for (var i = 0; i < this.values.length; i++)
      if (this.values[i].indexOf(name) == 0)
        ret.push(this.values[i]);
    return ret;
  });

//Third function with two arguments
  addMethod(ninjas, "find", function(first, last){
    var ret = [];
    for (var i = 0; i < this.values.length; i++)
      if (this.values[i] == (first + " " + last))
        ret.push(this.values[i]);
    return ret;
  });


//Now you can do:
ninjas.find();
ninjas.find("Sam");
ninjas.find("Dean", "Edwards")
</script>
Max Cabrera
quelle
0

Ich möchte Unterfunktionen innerhalb einer übergeordneten Funktion hinzufügen, um die Fähigkeit zu erreichen, zwischen Argumentgruppen für dieselbe Funktionalität zu unterscheiden.

var doSomething = function() {
    var foo;
    var bar;
};

doSomething.withArgSet1 = function(arg0, arg1) {
    var obj = new doSomething();
    // do something the first way
    return obj;
};

doSomething.withArgSet2 = function(arg2, arg3) {
    var obj = new doSomething();
    // do something the second way
    return obj;
};
km6zla
quelle
0

Was Sie erreichen möchten, tun Sie am besten mit der lokalen Argumentvariablen der Funktion .

function foo() {
    if (arguments.length === 0) {
        //do something
    }
    if (arguments.length === 1) {
        //do something else
    }
}

foo(); //do something
foo('one'); //do something else

Eine bessere Erklärung, wie dies funktioniert, finden Sie hier .

jbarnett
quelle
Und was ist mit der Kollisionserkennung? Dies ist eine gute Möglichkeit, parameterlose Funktionen zu verwenden oder die Existenz zu überprüfen, aber keine wirklich bewährte Methode, wenn es um Überladung geht.
Travis J