2016-04-06 13 views
2

Was ist eine gängige Methode zur Implementierung einer JavaScript-Funktion, deren mittlere Argumente optional sind, aber das letzte Argument benötigt wird? Eine idiomatische ES2015-Lösung ist bevorzugt.Idiomatische Möglichkeit, mittlere Argumente optional zu machen

Z. B., ich sehe Funktionen häufig, die auf verschiedene Weise aufgerufen werden kann, wie folgt aus:

func(firstArg, callback); 
func(firstArg, options, callback); 

Also eigentlich das, was passiert ist, dass die Anzahl der Argumente, die Interpretation jedes Argument betrifft.

Ich weiß, ich kann damit umgehen, indem die Länge der Argumente, so etwas wie diese Überprüfung:

//  func(firstArg, options, callback); 
// or: func(firstArg, callback); 
function (firstArg, ...args) { 
    let options = {}; 
    if (args.length > 1) { 
     options = args.shift(); 
    } 
    let callback = args[0]; 
    // And do stuff ... 
} 

Aber es scheint klobig. Gibt es einen besseren Weg, dies zu tun?

+0

Übergeben Sie stattdessen ein Objekt. – Andy

+0

Das Argument 'options' ist das Objekt. – brianmearns

+1

Die meisten Sprachen erzwingen ein * nur optionale Argumente können einer optionalen Argument * Regel für variadische Funktionen folgen, um diese Verwirrung/Ungeschicklichkeit an erster Stelle zu vermeiden. –

Antwort

1

Verwenden ..args und pop() der Rückruf aus dem Array:

function thing(...args) { 
    var cb = args.pop(); 
    //... args is now [1, obj] 
    cb(args[0]); 
} 

thing(1, { a: 1 }, function (data) { 
    console.log(data); // 1 
}); 
+0

OP, stellen Sie sicher, dass Sie testen, dass 'cb' ist eine Funktion .. :) – Andy

0

Ein idiomatischer Weg wäre Typprüfung einzubeziehen. Sie können auch Standardparameter nutzen.

function test(firstArg, callback, options = {}) { 
    if (typeof options == 'function') { 
    callback = arguments[2]; 
    options = arguments[1]; 
    } 

} 

Dies gewährleistet nicht nur, dass Sie eine Options Objekt immer haben, aber funktioniert auch, wenn jemand die Argumente für callback und options schaltet. Es spielt also keine Rolle, ob die Optionen an zweiter oder letzter Stelle stehen. Außerdem und vielleicht noch wichtiger sagt der Quellcode klar seine Absicht aus.

+0

Ich stimme zu, das würde funktionieren, aber ich stimme nicht zu, dass es idiomatische für ES6 oder Node ist. In der Tat glaube ich, dass "Argumente" in ES6 veraltet sind (oder zumindest davon abgehalten werden), und ich sehe sehr wenig Typprüfungen in JavaScript. In beiden Fällen finde ich die Möglichkeit, Optionen in verschiedenen Ordnungen ein schlechtes Muster, insbesondere weil es nicht allgemein ist; es kann nur in dem Fall getan werden, wo Sie überprüfen können, um zu bestimmen, welches Argument welches ist (würde in dem spezifischen Fall gut funktionieren, den ich umrissen habe). – brianmearns

+0

@ sh1ftst0rm Wenn Sie sich die populären Bibliotheken ansehen, werden Sie sehen, dass die Typprüfung ein gängiges Idiom ist. "Argumente" werden weder entmutigt noch missbilligt. Tatsächlich wurde es sogar verbessert. Mit dem Aufkommen des Spread-Operators ist es jedoch von begrenztem Nutzen. Wenn Sie über schlechte Muster sprechen wollen, sprechen Sie über ein optionales mittleres Argument. Wenn Sie die Möglichkeit finden, Argumente in beliebiger Reihenfolge zu übergeben, sollten Sie sich fragen, ob mehrere Argumente sinnvoll sind. Jetzt, wenn Sie nie in Ihrem Leben die Bestellung falsch haben, dann bin ich bereit, meine Meinung zu ändern. – zeroflagL

+0

Wir können es wahrscheinlich ertragen, dies eine Stufe tiefer zu nehmen. Schlechte Muster oder nicht, optionale mittlere Argumente sind im Knoten extrem üblich, und es gibt einen großen Unterschied zwischen diesen und den Argumenten in beliebiger Reihenfolge. Natürlich ist es immer ein Problem, die korrekte Reihenfolge der Argumente zu finden, aber ich denke, dass es besser ist, das mit etwas wie Curry oder einem Builder-Muster zu lösen.Wenn der aufrufende Code die Reihenfolge bestimmter Argumente vertauscht, aber keine anderen, dann fleht er um Ärger. Es ist besser, nur eine feste Reihenfolge einzuhalten und sie dazu zu bringen, sie zu lernen, anstatt Verwirrung zu stiften, indem man überall verschiedene Befehle hat. – brianmearns