Ustaw domyślną wartość parametru dla funkcji JavaScript


2366

Chciałbym, aby funkcja JavaScript miała opcjonalne argumenty, dla których ustawiłem wartość domyślną, które są używane, jeśli wartość nie jest zdefiniowana (i ignorowana, jeśli wartość zostanie przekazana). W Ruby możesz to zrobić w następujący sposób:

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

Czy to działa w JavaScript?

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

Odpowiedzi:


3296

W ES6 / ES2015 parametry domyślne są zgodne ze specyfikacją języka.

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

po prostu działa.

Odniesienie: parametry domyślne - MDN

Domyślne parametry funkcji pozwalają na zainicjowanie parametrów formalnych wartościami domyślnymi, jeśli nie zostanie przekazana żadna wartość lub niezdefiniowana .

Możesz także symulować domyślne parametry nazwane poprzez destrukcję :

// the `= {}` below lets you call the function without any parameters
function myFor({ start = 5, end = 1, step = -1 } = {}) { // (A)
    // Use the variables `start`, `end` and `step` here
    ···
}

Pre ES2015 ,

Jest wiele sposobów, ale jest to moja preferowana metoda - pozwala przekazać wszystko, co chcesz, w tym fałsz lub zero. ( typeof null == "object")

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}

216
Możesz go również zakapsułkować jako taki: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }a następnie możesz nazwać to jakoa = defaultFor(a, 42);
Camilo Martin

6
@SiPlus i masz dodatkowe błędy referencyjne bezpłatnie podczas próby użycia undefinedobiektów: p Nawet jeśli może działać z niektórymi przeglądarkami i może być szybszy, nullwciąż jest obiektem i undefinedodnosi się do prymitywnego typu, który próbuje powiedzieć, że istnieje nic, nawet tutaj null. Zobacz oba przypadki w skrócie: JavaScript / Reference / Global_Objects / undefined .
Sampo Sarrala - codidact.org

9
jeśli porównasz z właściwością obiektu, typeofjest to zbędne. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }Nie spowoduje to wyrzucenia błędów odniesienia i jest zwięzłe.
Dziamid

10
Wiem, że to naprawdę niewielkie, ale nie podoba mi się to, jak przypisujesz a = ai b = bkiedy te parametry nie są niezdefiniowane. Również ten trójskładnikowy operator z nieco skomplikowanymi warunkami może być trudny do odczytania dla przyszłych opiekunów. Wolałbym następującą składnię: if (typeof a == 'undefined') a = 42- bez niepotrzebnego przypisania plus trochę łatwiejszy do odczytania.
Daddy32,

12
Czy jest jakiś powód do korzystania typeof? Łatwiej byłoby to zrobić a === undefined. Plus w ten sposób dostaniesz błąd referencyjny, jeśli popełnisz błąd w pisowni undefinedzamiast w ciągu.
Abe Voelker,

599
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

Przypisuje to delete_afterwartość, delete_afterjeśli nie jest to wartość falsey, w przeciwnym razie przypisuje ciąg "my default here". Aby uzyskać więcej informacji, sprawdź ankietę Douga Crockforda na temat języka oraz sekcję Operatory .

Takie podejście nie działa, jeśli chcesz przekazać w falsey wartości tj false, null, undefined, 0lub "". Jeśli chcesz przekazać wartości falsey , musisz użyć metody z odpowiedzi Toma Rittera .

W przypadku wielu parametrów funkcji często przydatne jest zezwolenie konsumentowi na przekazanie argumentów parametrów w obiekcie, a następnie scalenie tych wartości z obiektem zawierającym wartości domyślne dla funkcji

function read_file(values) {
    values = merge({ 
        delete_after : "my default here"
    }, values || {});

    // rest of code
}

// simple implementation based on $.extend() from jQuery
function merge() {
    var obj, name, copy,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length;

    for (; i < length; i++) {
        if ((obj = arguments[i]) != null) {
            for (name in obj) {
                copy = obj[name];

                if (target === copy) {
                    continue;
                }
                else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    return target;
};

używać

// will use the default delete_after value
read_file({ file: "my file" }); 

// will override default delete_after value
read_file({ file: "my file", delete_after: "my value" }); 

115
Uważam to za niewystarczające, ponieważ mogę chcieć podać fałsz.
Tom Ritter

52
Uważam, że jest odpowiedni w większości sytuacji
Russ Cam

50
Ponieważ nie działa dla wartości falsey, może stworzyć koszmar konserwacji. Trochę kodu, który zawsze był wcześniej przekazywany zgodnie z prawdą, i nagle zawodzi, ponieważ przekazywany jest falsey, należy prawdopodobnie unikać tam, gdzie dostępne jest bardziej niezawodne podejście.
jinglesthula

1
Dlaczego w tym przypadku delete_afternie otrzymano wyniku boolowskiego wyrażenia delete_after || "my default value"?
xbonez

3
lub możesz po prostu ustawić domyślną wartość falsey - która i tak jest ogólnie dobrą wartością domyślną (np. fałsz dla booli, pusty ciąg dla łańcuchów, 0 dla liczb itp.) - w takim przypadku tak naprawdę nie ma znaczenia, co było przeszedł.
Mark Brackett

150

Uważam, że coś takiego jest bardziej zwięzłe i czytelne osobiście.

function pick(arg, def) {
   return (typeof arg == 'undefined' ? def : arg);
}

function myFunc(x) {
  x = pick(x, 'my default');
} 

6
Aktualizacja: Jeśli używasz już underscore.js, uważam, że jeszcze lepiej go używać _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. Korzystanie z globalnej przestrzeni nazw, jak pokazano w tej odpowiedzi, jest przez wielu uważane za złą praktykę. Możesz także rozważyć uruchomienie własnego narzędzia do tego wspólnego zadania (np. util.default(arg, "defaul value")), Jeśli nie chcesz używać podkreślenia, ale w większości przypadków wcześniej lub później używam podkreślenia, nie ma sensu wymyślać koła.
andersand

2
Naprawdę polecam ten, używam go i nazywam go „por”, co oznacza „parametr lub”
super

2
Nie mów typeof arg == 'undefined', zamiast tego powiedz arg === undefined
OsamaBinLogin

3
@OsamaBinLogin to, co mówisz, jest poprawne dla obecnego JS - starszy test trwa, ponieważ w niektórych przeglądarkach możliwe było nadpisanie undefinedinną wartością, co spowodowało, że test się nie powiódł.
Alnitak

2
@Alnitak: Nadal można przesłonić undefined. Tak więc nadal dobrym pomysłem jest użycie typeofi 'undefined'.
LS

63

W ECMAScript 6 będziesz w stanie napisać dokładnie to, co masz:

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

Spowoduje to ustawienie delete_after, aby falsejeśli to nie jest obecny lub undefined. Możesz korzystać z funkcji ES6, takich jak ta, dzisiaj z transpilerami, takimi jak Babel .

Aby uzyskać więcej informacji, zobacz artykuł MDN .


1
ECMAScript 6 Przypuszczam ... (sam bym poprawił, ale nie mogę edytować <6 znaków)
Zac

1
Oczekiwanie na przeglądarkę dostanie ECMAScript 6
Adriano Resende

1
Do czego Babel to przełoży?
harryg


2
Oto tabela zgodności dla ES6 kangax.github.io/compat-table/es6/#default_function_parameters Niestety ta składnia nie jest jeszcze obsługiwana .
freemanoid,

27

Domyślne wartości parametrów

Z ES6 możesz zrobić jeden z najczęstszych idiomów JavaScriptzwiązanych z ustawieniem wartości domyślnej parametru funkcji. Sposób, w jaki robiliśmy to od lat, powinien wyglądać znajomo:

function foo(x,y) {
 x = x || 11;
 y = y || 31;
 console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17

Ten wzór jest najczęściej używany, ale jest niebezpieczny, gdy przekazujemy wartości takie jak

foo(0, 42)
foo( 0, 42 ); // 53 <-- Oops, not 42

Dlaczego? Ponieważ 0 is falsy, a więc x || 11 results in 11, a nie bezpośrednio przekazane w 0. Aby naprawić tę gotcha, niektórzy zamiast tego wypiszą czek bardziej dosłownie:

function foo(x,y) {
 x = (x !== undefined) ? x : 11;
 y = (y !== undefined) ? y : 31;
 console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17

możemy teraz zbadać ładną, pomocną składnię dodaną od dnia, ES6aby usprawnić przypisywanie wartości domyślnych do brakujących argumentów:

function foo(x = 11, y = 31) {
 console.log( x + y );
}

foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`

x = 11deklaracja funkcji jest bardziej podobna x !== undefined ? x : 11do znacznie popularniejszego idiomux || 11

Wyrażenia wartości domyślnej

Functionwartości domyślne mogą być czymś więcej niż zwykłymi wartościami, takimi jak 31; mogą być dowolnym prawidłowym wyrażeniem, nawet function call:

function bar(val) {
 console.log( "bar called!" );
 return y + val;
}
function foo(x = y + 3, z = bar( x )) {
 console.log( x, z );
}
var y = 5;
foo(); // "bar called"
 // 8 13
foo( 10 ); // "bar called"
 // 10 15
y = 6;
foo( undefined, 10 ); // 9 10

Jak widać, wyrażenia wartości domyślnych są leniwie oceniane, co oznacza, że ​​są uruchamiane tylko wtedy, gdy są potrzebne - to znaczy, gdy argument parametru jest pominięty lub niezdefiniowany.

Wyrażenie wartości domyślnej może być nawet wywołaniem wyrażenia funkcji wbudowanej - zwykle nazywanym wyrażeniem funkcji natychmiast wywołanej (IIFE):

function foo( x =
 (function(v){ return v + 11; })( 31 )
) {
 console.log( x );
}
foo(); // 42

13

to rozwiązanie działa dla mnie w js:

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

4
Co się stanie, jeśli delete_afterjest 0lub null? W tych przypadkach nie będzie działać poprawnie.
Dmitri Pavlutin,

@StephanBijzitter byłoby to prawdą tylko w niektórych przypadkach. Ale jeśli chcesz tylko, aby wartości domyślne były rozbrojone, to nie działało, ponieważ 0 lub null! === false.
Rutrus

@Rutrus: Nic nie rozumiem, co powiedziałeś.
Stephan Bijzitter

Co delete_after = delete_after === undefined ? false : delete_after?
aashah7

10

Wystarczy użyć jawnego porównania z niezdefiniowanym.

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

10

Zdecydowanie zaleciłbym szczególną ostrożność podczas używania domyślnych wartości parametrów w javascript. To często powoduje błędy, gdy używany w połączeniu z funkcja wyższego rzędu, takich jak forEach, mapi reduce. Weźmy na przykład następujący wiersz kodu:

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

parseInt ma opcjonalną function parseInt(s, [podstawkę drugiego parametru, =10])ale wywołania map parseIntz trzema argumentami: ( element , indeks i tablica ).

Sugeruję oddzielenie wymaganych parametrów od argumentów o wartości opcjonalnej / domyślnej. Jeśli twoja funkcja przyjmuje 1,2 lub 3 wymagane parametry, dla których żadna wartość domyślna nie ma sensu, nadaj im parametry pozycyjne dla funkcji, wszelkie parametry opcjonalne powinny występować jako nazwane atrybuty pojedynczego obiektu. Jeśli twoja funkcja zajmuje 4 lub więcej, być może sensowniej jest podać wszystkie argumenty za pomocą atrybutów parametru pojedynczego obiektu.

W twoim przypadku proponuję napisać funkcję DeleteFile takiego: ( edytowane za instead „s komentarzach ) ...

// 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);

Uruchomienie powyższego fragmentu ilustruje niebezpieczeństwa kryjące się za domyślnymi wartościami argumentów dla nieużywanych parametrów.


1
To „lepsze rozwiązanie” jest dość nieczytelne. Wolałbym raczej sprawdzić typ zmiennej jak typeof deleteAfter === 'bool'i w przeciwnym razie wyrzucić wyjątek. Dodatkowo w przypadku korzystania z metod takich jak map / foreach itp. Należy ich używać ostrożnie i łączyć wywoływane funkcje z funkcją anonimową. ['1', '2', '3'].map((value) => {read_file(value);})
zamiast

Trafne spostrzeżenie. Starałem się unikać używania bibliotek we fragmencie kodu, ale ten idiom jest dość niechlujny w czystym javascript. Osobiście użyłbym getmetody lodash, aby pobrać deleteAfter. Zgłaszanie wyjątku, jeśli typeof 'deleteAfter' !== 'bool'może być również dobrym rozsądnym środkiem. Nie lubię projektować metod, które wymagają od osoby dzwoniącej „zachowania ostrożności”. Ostrożność jest obowiązkiem funkcji, a nie osoby dzwoniącej. Końcowe zachowanie powinno być zgodne z zasadą najmniejszego zaskoczenia.
Doug Coburn,

Zgadzam się, że tej metody nie należy pisać tak, że jej wywołanie może złamać jej zachowanie. Pamiętaj jednak, że funkcja jest jak model, a osoba dzwoniąca jest jak kontroler. Model powinien zadbać o przetwarzanie danych. Funkcja (metoda) powinna oczekiwać, że dane mogą być przekazywane w niewłaściwy sposób i obsługiwać je. Dlatego sprawdzanie typu parametru i zgłaszanie wyjątku jest najlepszym sposobem. Chociaż jest to bardziej złożone. Ale wciąż może uratować Cię przed podrapaniem się w głowę i wciąż pytać ... DLACZEGO TO NIE DZIAŁA ?! a potem ... DLACZEGO DZIAŁA ?!
zamiast


8

Będąc od dawna programistą C ++ (debiutantem w tworzeniu stron internetowych :)), kiedy po raz pierwszy zetknąłem się z tą sytuacją, wykonałem przypisanie parametrów w definicji funkcji, jak wspomniano w pytaniu, jak następuje.

function myfunc(a,b=10)

Ale uwaga, że ​​nie działa konsekwentnie w różnych przeglądarkach. Dla mnie działało to na Chrome na moim pulpicie, ale nie działało na Chrome na Androidzie. Bezpieczniejszą opcją, jak wspomniano powyżej, jest -

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

Zamiarem tej odpowiedzi nie jest powtórzenie tych samych rozwiązań, o czym inni już wspominali, ale poinformowanie, że przypisanie parametrów w definicji funkcji może działać w niektórych przeglądarkach, ale nie należy na niej polegać.


3
Przypisanie w ramach definicji funkcji również nie działa w IE 11, która jest najnowszą wersją IE dla Windows 8.1.
DiMono,

1
Jeśli ktoś zastanawia się, czy function myfunc(a,b=10)jest składnia ES6, w innych odpowiedziach znajdują się łącza do tabel zgodności.
gcampbell

7

Wszystkim zainteresowanym działaniem kodu w Microsoft Edge nie używaj wartości domyślnych w parametrach funkcji.

function read_file(file, delete_after = false) {
    #code
}

W tym przykładzie Edge zgłosi błąd „Oczekiwanie”) „”

Aby obejść ten problem, użyj

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

Od 08 sierpnia 2016 r. Jest to nadal problem


4

Zgodnie ze składnią

function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
   statements
}

możesz zdefiniować domyślną wartość parametrów formalnych. a także sprawdź niezdefiniowaną wartość za pomocą funkcji typeof .


4
function helloWorld(name, symbol = '!!!') {
    name = name || 'worlds';
    console.log('hello ' + name + symbol);
}

helloWorld(); // hello worlds!!!

helloWorld('john'); // hello john!!!

helloWorld('john', '(>.<)'); // hello john(>.<)

helloWorld('john', undefined); // hello john!!!

helloWorld(undefined, undefined); // hello worlds!!!

4

Użyj tego, jeśli chcesz użyć najnowszej ECMA6składni:

function myFunction(someValue = "This is DEFAULT!") {
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

To się nazywa default function parameters. Pozwala na zainicjowanie parametrów formalnych wartościami domyślnymi, jeśli nie zostanie przekazana żadna wartość lub niezdefiniowana. UWAGA : Nie będzie działać z przeglądarką Internet Explorer lub starszymi przeglądarkami.

Aby uzyskać maksymalną możliwą kompatybilność, użyj tego:

function myFunction(someValue) {
  someValue = (someValue === undefined) ? "This is DEFAULT!" : someValue;
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

Obie funkcje zachowują się dokładnie tak samo, jak każdy z tych przykładów opiera się na fakcie, że zmienna parametru będzie działać, undefinedjeśli nie zostanie przekazana żadna wartość parametru podczas wywoływania tej funkcji.


UWAGA: jak mówi @BlackBeard, funkcja (parametr = wartość) WONT działa z IE. Użyj zgodnej wersji.
MagicLAMP,

4

ES6: Jak już wspomniano w większości odpowiedzi, w ES6 można po prostu zainicjować parametr wraz z wartością.


ES5: Większość z podanych odpowiedzi nie są wystarczająco dobre dla mnie, bo zdarzają się sytuacje, w których może mam do przekazania wartości falsey takie jak 0, nulla undefineddo funkcji. Aby ustalić, czy parametr jest niezdefiniowany, ponieważ jest to wartość, którą podałem zamiast niezdefiniowanej, ponieważ w ogóle nie został zdefiniowany, robię to:

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}

3

function throwIfNoValue() {
throw new Error('Missing argument');
}
function foo(argValue = throwIfNoValue()) {
return argValue ;
}

Tutaj foo () jest funkcją, która ma parametr o nazwie argValue. Jeśli nie podamy tutaj niczego w wywołaniu funkcji, wówczas zostanie wywołana funkcja throwIfNoValue (), a zwrócony wynik zostanie przypisany do jedynego argumentu argValue. W ten sposób można użyć wywołania funkcji jako parametru domyślnego. Co czyni kod bardziej uproszczonym i czytelnym.

Ten przykład został zaczerpnięty stąd


3

Jeśli używasz ES6+, możesz ustawić parametry domyślne w następujący sposób:

function test (foo = 1, bar = 2) {
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

Jeśli potrzebujesz ES5składni, możesz to zrobić w następujący sposób:

function test(foo, bar) {
  foo = foo || 2;
  bar = bar || 0;
  
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

W powyższej składni ORużywany jest operator. OROperatora zawsze zwraca pierwszą wartość, jeśli to może być przekształcony w truejeśli nie zwraca wartość righthandside. Gdy funkcja jest wywoływana bez odpowiedniego argumentu, zmienna parametru ( barw naszym przykładzie) jest ustawiana undefinedprzez silnik JS. undefinedNastępnie jest konwertowany na false, a zatem ORoperator zwraca wartość 0.


3

Tak, używanie domyślnych parametrów jest w pełni obsługiwane w ES6 :

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

lub

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

ale wcześniej w ES5 można to łatwo zrobić:

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

Co oznacza, że ​​jeśli wartość tam jest, użyj wartości, w przeciwnym razie użyj drugiej wartości po ||operacji, która robi to samo ...

Uwaga: istnieje również duża różnica między nimi, jeśli przekażesz wartość do ES6, nawet wartość falsy, która zostanie zastąpiona nową wartością, coś w stylu nulllub ""... ale tylko ES5 zostanie zastąpiona, jeśli tylko przekazana wartość jest prawdą, ponieważ sposób ||działania ...


2

Jeśli z jakiegoś powodu jesteś nie na ES6 i przy użyciu lodasho to sposób zwięzły domyślnych parametrów funkcji za pomocą _.defaultTometody:

var fn = function(a, b) {
  a = _.defaultTo(a, 'Hi')
  b = _.defaultTo(b, 'Mom!')

  console.log(a, b)
}

fn()                 // Hi Mom!
fn(undefined, null)  // Hi Mom!
fn(NaN, NaN)         // Hi Mom!
fn(1)                // 1 "Mom!"
fn(null, 2)          // Hi 2
fn(false, false)     // false false
fn(0, 2)             // 0 2
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Które ustawią wartość domyślną, jeśli bieżąca wartość to NaN , zero lub niezdefiniowana


1

Sounds of Future

W przyszłości będziesz mógł „przenosić” jeden obiekt na inny (obecnie od 2019 r. NIEobsługiwany przez Edge !) - demonstracja, w jaki sposób używać tego obiektu do ładnych domyślnych opcji niezależnie od kolejności:

function test(options) {
    var options = {
       // defaults
       url: 'defaultURL',
       some: 'somethingDefault',
       // override with input options
       ...options
    };
    
    var body = document.getElementsByTagName('body')[0];
    body.innerHTML += '<br>' + options.url + ' : ' + options.some;
}
test();
test({});
test({url:'myURL'});
test({some:'somethingOfMine'});
test({url:'overrideURL', some:'andSomething'});
test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

Odwołanie do MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

... tymczasem tym, co obsługuje Edge DOES, jest Object.assign () (IE nie, ale naprawdę mam nadzieję, że możemy zostawić IE :)

Podobnie możesz zrobić

    function test(options) {
        var options = Object.assign({
           // defaults
           url: 'defaultURL',
           some: 'somethingDefault',
        }, options); // override with input options
        
        var body = document.getElementsByTagName('body')[0];
        body.innerHTML += '<br>' + options.url + ' : ' + options.some;
    }
    test();
    test({});
    test({url:'myURL'});
    test({some:'somethingOfMine'});
    test({url:'overrideURL', some:'andSomething'});
    test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

EDIT: W związku z uwagami dotyczącymi constopcji - problem z użyciem opcji stała w pozostałej części funkcji jest faktycznie nie że nie można tego zrobić, to po prostu, że nie można użyć zmiennej stałej we własnej deklaracji - trzeba aby dopasować nazewnictwo wejściowe do czegoś podobnego

function test(input_options){
   const options = {
     // defaults
     someKey:    'someDefaultValue',
     anotherKey: 'anotherDefaultValue',

     // merge-in input options
     ...input_options
   };

   // from now on use options with no problem
}

Problem polega na tym, że normalnie nigdy nie chcesz tego robić, ponieważ spowoduje to ponowne przypisanie opcji, które są już zdefiniowane, ale możesz użyć go z innym var, który byłby zgodny z prawem.
frank-dspeed

test funkcji (opcje) {/ * Opcje są zdefiniowane, spowoduje wyświetlenie błędu, jeśli użyjesz const options = {} teraz * /}
frank-dspeed

no nie globalny, gdy tworzysz funkcję i przekazujesz jako opcje nazwy argumentu, wtedy wewnątrz funkcji są zdefiniowane opcje wewnątrz funkcji (opt) {} opt jest zdefiniowany, nie możesz użyć const opt ​​wewnątrz tej funkcji, to jest źle, ponieważ robisz zmienna zmiana przypisania, jeśli robisz to często i wygląda to na twój ogólny wzorzec, jest to problem
frank-dspeed

@ google-frank-dspeed ah, masz na myśli, że nie możesz function(opt){ const opt = /*some merging*/; }? To na pewno nie zadziała, ponieważ użyjesz constzmiennej, zanim zostanie zadeklarowana - będziesz musiał dostosować -function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
jave.web

@ google-frank-dspeed i tak więcej nowych osób prawdopodobnie będzie się nad tym zastanawiać, więc dodałem kod do edycji :) więc dziękuję za wskazanie tego innym :)
jave.web

1

Aby tylko zaprezentować moje umiejętności (lol), powyższą funkcję można napisać nawet bez nazwanych argumentów, jak poniżej:

ES5 i wyżej

function foo() {
    a = typeof arguments[0] !== 'undefined' ? a : 42;
    b = typeof arguments[1] !== 'undefined' ? b : 'default_b';
    ...
}

ES6 i wyżej

function foo(...rest) {
    a = typeof rest[0] !== 'undefined' ? a : 42;
    b = typeof rest[1] !== 'undefined' ? b : 'default_b';
    ...
}

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

Poniższy kod może działać w tej sytuacji, w tym ECMAScript 6 (ES6), a także we wcześniejszych wersjach.

function read_file(file, delete_after) {
    if(delete_after == undefined)
        delete_after = false;//default value

    console.log('delete_after =',delete_after);
}
read_file('text1.txt',true);
read_file('text2.txt');

ponieważ wartość domyślna w językach działa, gdy wartość parametru funkcji jest pomijana podczas wywoływania, w JavaScript jest ona przypisana do niezdefiniowanej . To podejście nie wygląda atrakcyjnie programowo, ale ma kompatybilność wsteczną .


0

Tak, jest to określane jako parametr domyślny

Domyślne parametry funkcji pozwalają na zainicjowanie parametrów formalnych wartościami domyślnymi, jeśli nie zostanie przekazana żadna wartość lub niezdefiniowana.

Składnia:

function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
   statements
}

Opis:

Parametry funkcji są domyślnie niezdefiniowane Jednak w sytuacjach przydatne może być ustawienie innej wartości domyślnej. Tutaj mogą pomóc parametry domyślne.

W przeszłości ogólną strategią ustawiania wartości domyślnych było testowanie wartości parametrów w treści funkcji i przypisywanie wartości, jeśli są niezdefiniowane. Jeśli w wywołaniu nie podano żadnej wartości, jej wartość byłaby niezdefiniowana. Trzeba ustawić kontrolę warunkową, aby upewnić się, że parametr nie jest niezdefiniowany

Przy domyślnych parametrach w ES2015 sprawdzenie w ciele funkcji nie jest już konieczne. Teraz możesz po prostu umieścić wartość domyślną w nagłówku funkcji.

Przykład różnic:

// OLD METHOD
function multiply(a, b) {
  b = (typeof b !== 'undefined') ?  b : 1;
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5


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

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5

Różne przykłady składni:

Dopełnianie niezdefiniowane a inne wartości fałszowania:

Nawet jeśli wartość jest jawnie ustawiona podczas wywoływania, wartość argumentu num jest wartością domyślną.

function test(num = 1) {
  console.log(typeof num);
}

test();          // 'number' (num is set to 1)
test(undefined); // 'number' (num is set to 1 too)

// test with other falsy values:
test('');        // 'string' (num is set to '')
test(null);      // 'object' (num is set to null)

Oceniane w czasie połączenia:

Domyślny argument jest oceniany w czasie wywołania, więc w przeciwieństwie do niektórych innych języków, przy każdym wywołaniu funkcji tworzony jest nowy obiekt.

function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2], not [1, 2]


// This even applies to functions and variables
function callSomething(thing = something()) {
 return thing;
}

function something() {
  return 'sth';
}

callSomething();  //sth

Parametry domyślne są dostępne dla późniejszych parametrów domyślnych:

Napotkane już parametry są dostępne dla późniejszych parametrów domyślnych

function singularAutoPlural(singular, plural = singular + 's',
                        rallyingCry = plural + ' ATTACK!!!') {
  return [singular, plural, rallyingCry];
}

//["Gecko","Geckos", "Geckos ATTACK!!!"]
singularAutoPlural('Gecko');

//["Fox","Foxes", "Foxes ATTACK!!!"]
singularAutoPlural('Fox', 'Foxes');

//["Deer", "Deer", "Deer ... change."]
singularAutoPlural('Deer', 'Deer', 'Deer peaceably and respectfully \ petition the government for positive change.')

Funkcje zdefiniowane w treści funkcji:

Wprowadzono w Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30). Do funkcji zadeklarowanych w treści funkcji nie można odwoływać się do parametrów domyślnych i zgłaszać błąd ReferenceError (obecnie TypeError w SpiderMonkey, patrz błąd 1022967). Domyślne parametry są zawsze wykonywane jako pierwsze, następnie deklaracje funkcji wewnątrz treści funkcji.

// Doesn't work! Throws ReferenceError.
function f(a = go()) {
  function go() { return ':P'; }
}

Parametry bez wartości domyślnych po parametrach domyślnych:

Przed Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) następujący kod spowodował błąd SyntaxError. Zostało to naprawione w błędzie 777060 i działa zgodnie z oczekiwaniami w późniejszych wersjach. Parametry są nadal ustawiane od lewej do prawej, zastępując parametry domyślne, nawet jeśli istnieją późniejsze parametry bez wartości domyślnych.

function f(x = 1, y) {
  return [x, y];
}

f(); // [1, undefined]
f(2); // [2, undefined]

Zniszczony parametr z domyślnym przypisaniem wartości:

Przypisania wartości domyślnej można użyć z notacją przypisania niszczenia

function f([x, y] = [1, 2], {z: z} = {z: 3}) {
  return x + y + z;
}

f(); // 6

0

Innym podejściem do ustawiania domyślnych parametrów jest użycie mapy obiektów argumentów zamiast argumentów bezpośrednio. Na przykład,

const defaultConfig = {
 category: 'Animals',
 legs: 4
};

function checkOrganism(props) {
 const category = props.category || defaultConfig.category;
 const legs = props.legs || defaultConfig.legs;
}

W ten sposób można łatwo rozszerzyć argumenty i nie martwić się o niedopasowanie długości argumentów.


-1

Odpowiedź brzmi tak. W rzeczywistości istnieje wiele języków, które obsługują parametry domyślne. Python jest jednym z nich:

def(a, enter="Hello"):
   print(a+enter)

Mimo że jest to kod Pythona 3 z powodu nawiasów, domyślne parametry w funkcjach również działają w JS.

Na przykład w twoim przypadku:

function read_file(file, deleteAfter=false){
  console.log(deleteAfter);
}

read_file("test.txt");

Ale czasami tak naprawdę nie potrzebujesz parametrów domyślnych.

Możesz po prostu zdefiniować zmienną zaraz po uruchomieniu funkcji, tak jak to:

function read_file(file){
  var deleteAfter = false;
  console.log(deleteAfter);
}

read_file("test.txt");

W obu moich przykładach zwraca to samo. Ale czasami mogą się przydać, jak w bardzo zaawansowanych projektach.

Podsumowując, w JS można zastosować domyślne wartości parametrów. Ale jest to prawie to samo, co definiowanie zmiennej zaraz po uruchomieniu funkcji. Czasami jednak są nadal bardzo przydatne. Jak można zauważyć, domyślne wartości parametrów zajmują o 1 linię kodu mniej niż standardowy sposób definiowania parametru zaraz po uruchomieniu funkcji.

EDYCJA: I to jest bardzo ważne! To nie będziedziałać w IE. Zobacz dokumentację . Tak więc w IE musisz użyć metody „definiuj zmienną na początku funkcji”. Domyślne parametry nie będą działać w IE.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.