2651 Stimmen

Einen Standardparameterwert für eine JavaScript-Funktion festlegen

Ich möchte eine JavaScript-Funktion, um optionale Argumente, die ich einen Standard auf, die verwendet werden, wenn der Wert nicht definiert ist (und ignoriert, wenn der Wert übergeben wird). In Ruby kann man das so machen:

def read_file(file, delete_after = false)
  # code
end

Funktioniert das auch in JavaScript?

function read_file(file, delete_after = false) {
  // Code
}

16voto

Takács Zsolt Punkte 268

Diese Lösung funktioniert für mich in js:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}

4 Stimmen

Was passiert, wenn delete_after es 0 o null ? In diesen Fällen wird sie nicht korrekt funktionieren.

0 Stimmen

@StephanBijzitter das würde nur in einigen Fällen zutreffen. Aber wenn man nur die Standardwerte zu ungültigen Werten machen will, funktioniert das nicht, weil 0 oder null !=== false.

0 Stimmen

@Rutrus: Ich verstehe nichts von dem, was Sie gerade gesagt haben.

12voto

Doug Coburn Punkte 2257

Ich würde sehr empfehlen, extreme Vorsicht bei der Verwendung von Standard-Parameterwerte in Javascript. Es schafft oft Fehler, wenn sie in Verbindung mit Funktionen höherer Ordnung wie forEach , map und reduce . Betrachten Sie zum Beispiel diese Codezeile:

['1', '2', '3'].map(parseInt); // [1, NaN, NaN]

parseInt hat einen optionalen zweiten Parameter function parseInt(s, [ radix =10]) aber die Karte ruft parseInt mit drei Argumenten: ( Element , Index und array ).

Ich schlage vor, dass Sie Ihre erforderlichen Parameter von Ihren optionalen/standardmäßigen Argumenten trennen. Wenn Ihre Funktion 1, 2 oder 3 erforderliche Parameter benötigt, für die kein Standardwert sinnvoll ist, machen Sie sie zu Positionsparametern der Funktion, alle optionalen Parameter sollten als benannte Attribute eines einzelnen Objekts folgen. Wenn Ihre Funktion 4 oder mehr Parameter benötigt, ist es vielleicht sinnvoller, alle Argumente über Attribute eines einzelnen Objektparameters zu übergeben.

In Ihrem Fall würde ich vorschlagen, Sie schreiben Ihre deleteFile-Funktion wie folgt: ( bearbeitet per instead 's Kommentare )...

// unsafe
function read_file(fileName, deleteAfter=false) {
    if (deleteAfter) {
        console.log(`Reading and then deleting ${fileName}`);
    } else {
        console.log(`Just reading ${fileName}`);
    }
}

// better
function readFile(fileName, options) {
  const deleteAfter = !!(options && options.deleteAfter === true);
  read_file(fileName, deleteAfter);
}

console.log('unsafe...');
['log1.txt', 'log2.txt', 'log3.txt'].map(read_file);

console.log('better...');
['log1.txt', 'log2.txt', 'log3.txt'].map(readFile);

Die Ausführung des obigen Schnipsels veranschaulicht die Gefahren, die hinter Standardargumenten für nicht verwendete Parameter lauern.

1 Stimmen

Diese "bessere Lösung" ist ziemlich unübersichtlich. Ich würde eher empfehlen, den Variablentyp zu prüfen wie typeof deleteAfter === 'bool' und andernfalls eine Exception auslösen. Plus im Falle der Verwendung von Methoden wie map/foreach etc. nur verwenden sie mit Vorsicht und wrap aufgerufenen Funktionen mit anonymen Funktion. ['1', '2', '3'].map((value) => {read_file(value);})

0 Stimmen

Das ist ein gutes Argument. Ich habe versucht, die Verwendung von Bibliotheken in meinem Codeschnipsel zu vermeiden, aber dieses Idiom ist ziemlich chaotisch in reinem Javascript. Persönlich würde ich lodash's verwenden get Methode, um deleteAfter abzurufen. Es wird eine Ausnahme geworfen, wenn typeof 'deleteAfter' !== 'bool' kann auch eine gute Vorsichtsmaßnahme sein. Ich mag es nicht, Methoden zu entwerfen, die den Anrufer auffordern, "Vorsicht walten zu lassen". Vorsicht liegt in der Verantwortung der Funktion, nicht des Aufrufers. Das Endverhalten sollte dem Prinzip der geringsten Überraschung folgen.

0 Stimmen

Ich stimme zu, dass die Methode nicht so geschrieben sein sollte, dass der Aufruf das Verhalten kaputt machen kann. Aber bedenken Sie, dass die Funktion wie ein Modell ist, und der Aufrufer ist wie ein Controller. Das Modell sollte sich um die Verarbeitung der Daten kümmern. Die Funktion (Methode) sollte erwarten, dass die Daten falsch übergeben werden können und diese verarbeiten. Deshalb ist die Überprüfung des Parametertyps und das Auslösen einer Exception der beste Weg. Auch wenn es komplexer ist. Aber es kann Sie davor bewahren, sich den Kopf zu zerbrechen und immer wieder zu fragen... WARUM ES NICHT FUNKTIONIERT?! und dann... WARUM ES FUNKTIONIERT?!

11voto

Martin Wantke Punkte 3753

Verwenden Sie einfach einen expliziten Vergleich mit undefiniert.

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}

10voto

jshbrmn Punkte 1711

Als Update...mit ECMAScript 6 können Sie ENDLICH Standardwerte in der Deklaration von Funktionsparametern wie folgt festlegen:

function f (x, y = 7, z = 42) {
  return x + y + z
}

f(1) === 50

Wie referenziert von - http://es6-features.org/#DefaultParameterValues

13 Stimmen

Diese Antwort ist nicht sinnvoll, da sie ein Duplikat ist

9voto

vivek Punkte 337

Als langjähriger C++-Entwickler (Rookie in der Webentwicklung :)) habe ich, als ich das erste Mal auf diese Situation stieß, die Parameterzuweisung in der Funktionsdefinition wie in der Frage erwähnt wie folgt vorgenommen.

function myfunc(a,b=10)

Beachten Sie aber, dass diese Funktion nicht in allen Browsern gleich gut funktioniert. Bei mir funktionierte es mit Chrome auf meinem Desktop, aber nicht mit Chrome auf Android. Sicherere Option, wie viele oben erwähnt haben, ist -

    function myfunc(a,b)
    {
    if (typeof(b)==='undefined') b = 10;
......
    }

Die Absicht dieser Antwort ist nicht, die gleichen Lösungen zu wiederholen, die andere bereits erwähnt haben, sondern darüber zu informieren, dass die Parameterzuweisung in der Funktionsdefinition bei einigen Browsern funktionieren kann, aber verlassen Sie sich nicht darauf.

3 Stimmen

Die Zuweisung innerhalb der Funktionsdefinition funktioniert auch nicht im IE 11, der aktuellsten Version des IE für Windows 8.1.

1 Stimmen

Falls sich jemand wundert, function myfunc(a,b=10) ist ES6-Syntax, es gibt Links zu Kompatibilitätstabellen in anderen Antworten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X