Impostare un valore di parametro predefinito per una funzione JavaScript


2367

Vorrei che una funzione JavaScript avesse argomenti opzionali su cui ho impostato un valore predefinito, che vengono utilizzati se il valore non è definito (e ignorato se il valore viene passato). In Ruby puoi farlo in questo modo:

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

Funziona in JavaScript?

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

Risposte:


3298

Da ES6 / ES2015 , i parametri predefiniti sono nelle specifiche della lingua.

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

funziona e basta.

Riferimento: parametri predefiniti - MDN

I parametri di funzione predefiniti consentono di inizializzare i parametri formali con valori predefiniti se non viene passato alcun valore o non definito .

Puoi anche simulare i parametri nominati predefiniti tramite la destrutturazione :

// 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 ,

Ci sono molti modi, ma questo è il mio metodo preferito: ti permette di passare tutto quello che vuoi, incluso falso o nullo. ( typeof null == "object")

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

216
Puoi anche incapsularlo come tale: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }e quindi puoi chiamarlo comea = defaultFor(a, 42);
Camilo Martin

6
@SiPlus e hai ricevuto ulteriori errori di riferimento gratuitamente mentre provi a usare undefinedoggetti: p Anche se può funzionare con alcuni browser e potrebbe essere più veloce, nullè ancora un oggetto ed undefinedè un riferimento al tipo primitivo che sta cercando di dire che c'è niente qui, nemmeno null. Vedi qui, entrambi i casi in breve: JavaScript / Riferimento / Global_Objects / undefined .
Sampo Sarrala - codidact.org

9
se controlli contro la proprietà di un oggetto, allora typeofè ridondante. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }Ciò non genererà errori di riferimento ed è conciso.
Dziamid,

10
So che è davvero minore, ma non mi piace come stai assegnando a = ae b = bquando quei parametri non sono indefiniti. Inoltre, quell'operatore ternario con una condizione un po 'complicata può essere difficile da leggere per i futuri manutentori. Preferirei la seguente sintassi: if (typeof a == 'undefined') a = 42- nessuna assegnazione non necessaria più un po 'più facile da leggere.
Daddy32,

12
C'è qualche motivo per usare typeof? Sembrerebbe più semplice da fare a === undefined. Inoltre in questo modo si otterrebbe un errore di riferimento se si scrivesse erroneamente undefinedanziché inserirlo in una stringa.
Abe Voelker,

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

Questo assegna al delete_aftervalore di delete_afterse non è un valore falso , altrimenti assegna la stringa "my default here". Per maggiori dettagli, dai un'occhiata al sondaggio sulla lingua di Doug Crockford e dai un'occhiata alla sezione Operatori .

Questo approccio non funziona se si desidera passare a un Falsey valore vale a dire false, null, undefined, 0o "". Se richiedi il passaggio di valori di falsi, dovrai utilizzare il metodo nella risposta di Tom Ritter .

Quando si ha a che fare con una serie di parametri per una funzione, è spesso utile consentire al consumatore di passare gli argomenti dei parametri in un oggetto e quindi unire questi valori con un oggetto che contiene i valori predefiniti per la funzione

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

usare

// 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
Lo trovo insufficiente, perché potrei voler passare in falso.
Tom Ritter,

52
Trovo che sia adeguato per la maggior parte delle situazioni
Russ Cam

50
Poiché non funziona per i valori di falso, può creare un incubo di manutenzione. Un po 'di codice a cui sono sempre stati passati valori di verità prima e all'improvviso fallisce perché viene trasmesso un falso in cui si dovrebbe probabilmente evitare un approccio più solido.
jinglesthula,

1
Come mai, in questo caso, delete_afternon si ottiene il risultato booleano dell'espressione delete_after || "my default value"?
xbonez,

3
oppure, potresti semplicemente impostare un valore falso - che in genere è comunque un buon valore predefinito (ad es., falso per bool, stringa vuota per stringhe, 0 per numeri, ecc.) - nel qual caso non importa cosa fosse passato.
Mark Brackett il

150

Trovo che qualcosa di semplice come questo sia molto più conciso e leggibile personalmente.

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

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

6
Aggiornamento: se stai già utilizzando underscore.js lo trovo ancora meglio da usare _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. L'uso dello spazio dei nomi globale come mostrato in questa risposta è da molti considerato una cattiva pratica. Puoi anche prendere in considerazione il rotolamento della tua utility per questo compito comune (ad es. util.default(arg, "defaul value")) Se non voglio usare il carattere di sottolineatura, ma alla fine finisco per usare il carattere di sottolineatura prima o poi comunque inutile reinventare la ruota.
andersand,

2
In realtà lo consiglio, lo uso e lo chiamo "por" che sta per "parametro o"
super

2
Non dite typeof arg == 'undefined', invece dite arg === undefined
OsamaBinLogin

3
@OsamaBinLogin ciò che dici è corretto per l'attuale JS: il test più vecchio persiste perché in alcuni browser era possibile sovrascrivere undefinedcon qualche altro valore, causando il fallimento del test.
Alnitak,

2
@Alnitak: è ancora possibile eseguire l'override undefined. Quindi, è comunque una buona idea usare typeofe 'undefined'.
LS

63

In ECMAScript 6 sarai effettivamente in grado di scrivere esattamente quello che hai:

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

Questo verrà impostato delete_aftersu falsese non è presente o undefined. È possibile utilizzare le funzionalità ES6 come questa oggi con transpiler come Babel .

Vedi l'articolo MDN per ulteriori informazioni .


1
ECMAScript 6 Suppongo ... (avrei corretto da solo ma non posso apportare modifiche <6 caratteri)
Zac

1
In attesa del browser, ottieni ECMAScript 6
Adriano Resende

1
A cosa avrebbe trasposto Babele questo?
harryg,


2
Ecco la tabella di compatibilità per ES6 kangax.github.io/compat-table/es6/#default_function_parameters Purtroppo questa sintassi non è ancora supportata .
massone

27

Valori dei parametri predefiniti

Con ES6, puoi fare forse uno dei modi di dire più comuni in JavaScriptrelazione all'impostazione di un valore predefinito per un parametro di funzione. Il modo in cui lo facciamo da anni dovrebbe sembrare abbastanza familiare:

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

Questo modello è più usato, ma è pericoloso quando passiamo valori come

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

Perché? Perché la0 is falsy , e quindi il x || 11 results in 11, non il passato direttamente in 0. Per correggere questo gotcha, alcune persone invece scriveranno il controllo più verbalmente in questo modo:

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

possiamo ora esaminare una sintassi utile utile aggiunta da a ES6per semplificare l'assegnazione di valori predefiniti agli argomenti mancanti:

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 = 11in una dichiarazione di funzione è più simile x !== undefined ? x : 11al linguaggio molto più comunex || 11

Espressioni di valori predefiniti

Functioni valori predefiniti possono essere più di semplici valori come 31; possono essere qualsiasi espressione valida, anche un 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

Come puoi vedere, le espressioni dei valori predefiniti vengono valutate pigramente, il che significa che vengono eseguite solo se e quando sono necessarie, ovvero quando l'argomento di un parametro viene omesso o non definito.

Un'espressione di valore predefinita può anche essere una chiamata di espressione di funzione incorporata, comunemente denominata Espressione di funzione immediatamente richiamata (IIFE):

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

13

quella soluzione è lavoro per me in js:

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

4
Cosa succede se delete_afterè 0o null? Non funzionerà correttamente per questi casi.
Dmitri Pavlutin,

@StephanBijzitter sarebbe vero solo in alcuni casi. Ma se vuoi solo che i valori predefiniti non vengano impostati, questo non ha funzionato, perché 0 o null! === false.
Rutrus,

@Rutrus: non capisco niente di quello che hai appena detto.
Stephan Bijzitter,

Che dire delete_after = delete_after === undefined ? false : delete_after?
aashah7,

10

Basta usare un confronto esplicito con undefined.

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

10

Consiglio vivamente estrema cautela quando si utilizzano i valori dei parametri predefiniti in JavaScript. Si crea spesso bug se usato in combinazione con funzioni di ordine superiore come forEach, mape reduce. Ad esempio, considera questa riga di codice:

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

parseInt ha un secondo parametro opzionale function parseInt(s, [radix=10]) ma mappa chiamate parseIntcon tre argomenti: ( elemento , indice e matrice ).

Ti suggerisco di separare i parametri richiesti dagli argomenti valutati facoltativi / predefiniti. Se la tua funzione accetta 1,2 o 3 parametri richiesti per i quali nessun valore predefinito ha senso, rendili parametri posizionali per la funzione, tutti i parametri opzionali devono seguire come attributi nominati di un singolo oggetto. Se la tua funzione richiede 4 o più, forse ha più senso fornire tutti gli argomenti tramite gli attributi di un singolo parametro oggetto.

Nel tuo caso ti suggerirei di scrivere la tua funzione deleteFile in questo modo: ( modificato per instead i commenti di ) ...

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

L'esecuzione dello snippet sopra riportato illustra i pericoli in agguato dietro i valori degli argomenti predefiniti per i parametri non utilizzati.


1
Questa "soluzione migliore" è piuttosto illeggibile. Preferirei piuttosto controllare il tipo di variabile come typeof deleteAfter === 'bool'e gettare Eccezione in caso contrario. Inoltre, in caso di utilizzo di metodi come map / foreach ecc., Basta usarli con cautela e avvolgere chiamate funzioni con funzione anonima. ['1', '2', '3'].map((value) => {read_file(value);})
invece il

È un buon punto. Stavo cercando di evitare di usare le librerie nel mio frammento di codice, ma questo idioma è piuttosto disordinato in javascript puro. Personalmente, userei il getmetodo lodash per recuperare deleteAfter. Gettare un'eccezione se typeof 'deleteAfter' !== 'bool'può anche essere una buona misura prudente. Non mi piacciono i metodi di progettazione che richiedono al chiamante di "usare cautela". L'attenzione è responsabilità della funzione, non del chiamante. Il comportamento finale dovrebbe seguire il principio della minima sorpresa.
Doug Coburn,

Sono d'accordo, quel metodo non dovrebbe essere scritto nel modo in cui, chiamandolo, può spezzarne il comportamento. Ma tieni presente che la funzione è come un modello e che il chiamante è come un controller. Il modello dovrebbe occuparsi del trattamento dei dati. La funzione (metodo) dovrebbe prevedere che i dati possano essere passati in modo errato e gestirli. Ecco perché il controllo del tipo di parametro e dell'eccezione è il modo migliore. Anche se è più complesso. Ma comunque può salvarti dal grattarti la testa e continuare a chiedere ... PERCHÉ NON FUNZIONA ?! e poi ... PERCHÉ FUNZIONA ?!
invece il


8

essendo uno sviluppatore C ++ da molto tempo (Rookie allo sviluppo web :)), quando mi sono imbattuto per la prima volta in questa situazione, ho fatto l'assegnazione dei parametri nella definizione della funzione, come è menzionato nella domanda, come segue.

function myfunc(a,b=10)

Ma attenzione che non funziona in modo coerente tra i browser. Per me ha funzionato su Chrome sul mio desktop, ma non ha funzionato su Chrome su Android. L'opzione più sicura, come molti hanno menzionato sopra è -

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

L'intenzione per questa risposta non è quella di ripetere le stesse soluzioni, ciò che altri hanno già menzionato, ma di informare che l'assegnazione dei parametri nella definizione della funzione può funzionare su alcuni browser, ma non fare affidamento su di essa.


3
Anche l'assegnazione all'interno della definizione della funzione non funziona in IE 11, che è la versione più recente di IE per Windows 8.1.
DiMono,

1
Nel caso qualcuno si function myfunc(a,b=10)stia chiedendo, è la sintassi ES6, ci sono collegamenti a tabelle di compatibilità in altre risposte.
gcampbell,

7

A chiunque sia interessato a far funzionare il codice in Microsoft Edge, non utilizzare i valori predefiniti nei parametri della funzione.

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

In quell'esempio Edge genererà un errore "Expecting ')'"

Per aggirare questo uso

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

A partire dall'8 agosto 2016 questo è ancora un problema


4

Secondo la sintassi

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

puoi definire il valore predefinito dei parametri formali. e controlla anche il valore indefinito usando la funzione 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

Utilizzare questo se si desidera utilizzare la ECMA6sintassi più recente :

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

Si chiama default function parameters. Consente di inizializzare i parametri formali con valori predefiniti se non viene passato alcun valore o non definito. NOTA : non funzionerà con Internet Explorer o browser meno recenti.

Per la massima compatibilità possibile utilizzare questo:

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

Entrambe le funzioni hanno lo stesso identico comportamento di ciascuno di questi esempi, basandosi sul fatto che la variabile del parametro sarà undefinedse nessun valore di parametro è stato passato quando si chiama quella funzione.


NOTA: come dice @BlackBeard, la funzione (param = value) NON funzionerà con IE. Usa la versione compatibile.
MagicLAMP

4

ES6: Come già accennato nella maggior parte delle risposte, in ES6 è possibile semplicemente inizializzare un parametro insieme a un valore.


ES5: La maggior parte delle risposte fornite non è abbastanza buona per me perché ci sono occasioni in cui potrei dover passare valori falsi come 0, nulle undefinedad una funzione. Per determinare se un parametro non è definito perché questo è il valore che ho passato anziché indefinito a causa del fatto che non sono stato definito affatto, faccio questo:

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

Qui foo () è una funzione che ha un parametro chiamato argValue. Se non passiamo nulla nella chiamata della funzione qui, verrà chiamata la funzione throwIfNoValue () e il risultato restituito verrà assegnato all'unico argomento argValue. Ecco come una chiamata di funzione può essere utilizzata come parametro predefinito. Il che rende il codice più semplice e leggibile.

Questo esempio è stato preso da qui


3

Se si utilizza ES6+è possibile impostare i parametri predefiniti nel modo seguente:

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

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

Se hai bisogno della ES5sintassi puoi farlo nel modo seguente:

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

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

Nella sintassi precedente ORviene utilizzato l' operatore. L' ORoperatore restituisce sempre il primo valore se questo può essere convertito in truecaso contrario restituisce il valore sul lato destro. Quando la funzione viene chiamata senza argomento corrispondente, la variabile del parametro ( barnel nostro esempio) viene impostata undefineddal motore JS. undefinedViene quindi convertito in falso e quindi l' ORoperatore restituisce il valore 0.


3

Sì, l'utilizzo dei parametri predefiniti è pienamente supportato in ES6 :

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

o

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

ma prima in ES5 potresti facilmente farlo:

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

Ciò significa che se il valore è presente, utilizzare il valore, altrimenti utilizzare il secondo valore dopo l' ||operazione che fa la stessa cosa ...

Nota: c'è anche una grande differenza tra quelli se si passa un valore a ES6 uno anche se il valore è falso, che verrà sostituito con un nuovo valore, qualcosa di simile nullo ""... ma ES5 verrà sostituito solo se solo il valore passato è vero, è perché il modo in cui ||funziona ...


2

Se per qualche motivo non siete non sul ES6 e si utilizza lodash: ecco un modo conciso per i parametri di funzione di default tramite _.defaultToil metodo:

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>

Che imposterà il valore predefinito se il valore corrente è NaN , null o non definito


1

Suoni del futuro

In futuro, sarai in grado di "diffondere" un oggetto su un altro (attualmente dal 2019 NON supportato da Edge !) - dimostrazione di come utilizzarlo per opzioni predefinite piacevoli indipendentemente dall'ordine:

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'});

Riferimento MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

... nel frattempo ciò che Edge DOES supporta è Object.assign () (IE no, ma spero davvero che potremo lasciare IE alle spalle :))

Allo stesso modo potresti fare

    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: A causa di commenti constopzioni - il problema con l'utilizzo di opzioni costanti nel resto della funzione è in realtà non è che non si può fare, è solo che non è possibile utilizzare la variabile costante nella propria dichiarazione - si avrebbe per adattare il nome dell'input a qualcosa di simile

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
}

Il problema è che di solito non lo vorrai mai fare in quanto ciò riassegnerà le opzioni che sono già definite ma puoi usarle con un altro var che sarebbe legittimo.
Frank-dspeed,

test funzionale (opzioni) {/ * Le opzioni sono definite genererà un errore se usi const options = {} now * /}
frank-dspeed

no non globale quando si crea una funzione e si passa come opzioni del nome dell'argomento, quindi all'interno delle opzioni della funzione viene definita all'interno della funzione (opt) {} opt è definita non è possibile utilizzare const opt ​​all'interno di quella funzione quindi questo è negativo perché lo si fa riassegnazione variabile se lo fai spesso e sembra che il tuo modello generale sia un problema
franc-dspeed

@ google-frank-dspeed ah, vuoi dire che non puoi farlo function(opt){ const opt = /*some merging*/; }? Che di sicuro non funzionerà perchéconstfunction test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
useresti la

@ google-frank-dspeed comunque molte nuove persone probabilmente si chiederanno questo, quindi ho aggiunto il codice how-to da modificare :) quindi grazie per
averlo

1

Giusto per mostrare anche le mie capacità (lol), la funzione sopra può essere scritta anche senza aver chiamato argomenti come di seguito:

ES5 e versioni successive

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

ES6 e versioni successive

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

Il codice seguente può funzionare in questa situazione, incluso ECMAScript 6 (ES6) e versioni precedenti.

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

poiché il valore predefinito nelle lingue funziona quando il valore del parametro della funzione viene ignorato durante la chiamata, in JavaScript viene assegnato a indefinito . Questo approccio non ha un aspetto attraente a livello di programmazione ma ha retrocompatibilità .


0

Sì, questo è indicato come parametro predefinito

I parametri di funzione predefiniti consentono di inizializzare i parametri formali con valori predefiniti se non viene passato alcun valore o non definito.

Sintassi:

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

Descrizione:

Parametri delle funzioni predefiniti su indefiniti Tuttavia, in situazioni potrebbe essere utile impostare un valore predefinito diverso. È qui che possono aiutare i parametri predefiniti.

In passato, la strategia generale per impostare i valori predefiniti era testare i valori dei parametri nel corpo della funzione e assegnare un valore se non definito. Se nella chiamata non viene fornito alcun valore, il suo valore sarebbe indefinito. Dovresti impostare un controllo condizionale per assicurarti che il parametro non sia indefinito

Con i parametri predefiniti in ES2015, il controllo nel corpo della funzione non è più necessario. Ora puoi semplicemente inserire un valore predefinito nell'intestazione della funzione.

Esempio delle differenze:

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

Diversi esempi di sintassi:

Riempimento non definito rispetto ad altri valori di falsità:

Anche se il valore viene impostato esplicitamente durante la chiamata, il valore dell'argomento num è quello predefinito.

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)

Valutato al momento della chiamata:

L'argomento predefinito viene valutato al momento della chiamata, quindi a differenza di altre lingue, un nuovo oggetto viene creato ogni volta che viene chiamata la funzione.

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

I parametri predefiniti sono disponibili per i parametri predefiniti successivi:

I parametri già rilevati sono disponibili per i parametri predefiniti successivi

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.')

Funzioni definite all'interno del corpo della funzione:

Introdotto in Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30). Le funzioni dichiarate nel corpo della funzione non possono essere riferite all'interno dei parametri predefiniti e generare un ReferenceError (attualmente un TypeError in SpiderMonkey, vedere il bug 1022967). I parametri predefiniti vengono sempre eseguiti per primi, le dichiarazioni di funzione all'interno del corpo della funzione vengono valutate in seguito.

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

Parametri senza valori predefiniti dopo i parametri predefiniti:

Prima di Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2), il codice seguente generava un SyntaxError. Questo problema è stato risolto nel bug 777060 e funziona come previsto nelle versioni successive. I parametri vengono comunque impostati da sinistra a destra, sovrascrivendo i parametri predefiniti anche se ci sono parametri successivi senza valori predefiniti.

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

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

Parametro destrutturato con assegnazione di valore predefinita:

È possibile utilizzare l'assegnazione di valori predefiniti con la notazione di assegnazione destrutturante

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

f(); // 6

0

Solo un approccio diverso per impostare i parametri predefiniti consiste nell'utilizzare la mappa degli oggetti degli argomenti, anziché gli argomenti direttamente. Per esempio,

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

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

In questo modo, è facile estendere gli argomenti e non preoccuparsi della mancata corrispondenza della lunghezza degli argomenti.


-1

La risposta è si. In effetti, ci sono molte lingue che supportano i parametri predefiniti. Python è uno di questi:

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

Anche se questo è il codice Python 3 a causa delle parentesi, i parametri predefiniti nelle funzioni funzionano anche in JS.

Ad esempio, e nel tuo caso:

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

read_file("test.txt");

Ma a volte non hai davvero bisogno di parametri predefiniti.

Puoi semplicemente definire la variabile subito dopo l'inizio della funzione, in questo modo:

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

read_file("test.txt");

In entrambi i miei esempi, restituisce la stessa cosa. Ma a volte potrebbero effettivamente essere utili, come in progetti molto avanzati.

Quindi, in conclusione, i valori dei parametri predefiniti possono essere utilizzati in JS. Ma è quasi la stessa cosa che definire una variabile subito dopo l'inizio della funzione. Tuttavia, a volte sono ancora molto utili. Come avrai notato, i valori dei parametri predefiniti accettano 1 riga di codice in meno rispetto al modo standard che definisce il parametro subito dopo l'avvio della funzione.

EDIT: E questo è molto importante! Questo non funzionerà in IE. Vedere la documentazione . Quindi con IE devi usare il metodo "Definisci variabile al massimo della funzione". I parametri predefiniti non funzioneranno in IE.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.