Imposta un valore di parametro predefinito per una funzione JavaScript

Vorrei che una funzione JavaScript avesse argomenti opzionali su cui imposto un valore predefinito, che viene utilizzato se il valore non è definito. 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 } 

Da ES6 / ES2015, i parametri predefiniti sono specificati nella lingua.

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

funziona

Riferimento: parametri di default – MDN

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

Puoi anche simulare i parametri con nome predefinito tramite 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 lascia passare tutto ciò che vuoi, incluso falso o nulla. ( typeof null == "object" )

 function foo(a, b) { a = typeof a !== 'undefined' ? a : 42; b = typeof b !== 'undefined' ? b : 'default_b'; ... } 
 function read_file(file, delete_after) { delete_after = delete_after || "my default here"; //rest of code } 

Questo assegna a delete_after il valore di delete_after se non è un valore falso altrimenti assegna la stringa "my default here" . Per ulteriori dettagli, controlla il sondaggio di Doug Crockford sulla lingua e controlla la sezione sugli operatori .

Questo approccio non funziona se si desidera passare un valore false cioè false , null , undefined , 0 o "" . Se richiedi il passaggio di valori falsi , devi utilizzare il metodo nella risposta di Tom Ritter .

Quando si ha a che fare con un numero di parametri per una funzione, è spesso utile consentire al consumatore di passare gli argomenti dei parametri in un object e quindi unire questi valori con un object 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" }); 

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

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

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

Questo imposta delete_after su false se non è presente o undefined . È ansible utilizzare le funzionalità ES6 come questa oggi con transpilers come Babel .

Vedere l’articolo MDN per ulteriori informazioni .

Valori dei parametri predefiniti

Con ES6, è ansible fare uno degli idiomi più comuni in JavaScript relativo all’impostazione di un valore predefinito per un parametro di funzione. Il modo in cui lo abbiamo fatto per 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 schema è più utilizzato, ma è pericoloso quando passiamo valori come

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

Perché? Perché lo 0 is falsy , e quindi x || 11 results in 11 x || 11 results in 11 , non quelli passati direttamente in 0. Per risolvere questo problema, alcune persone scriveranno invece il controllo in modo più verosimile come questo:

 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 

ora possiamo esaminare una bella syntax utile aggiunta a ES6 per semplificare l'assegnazione dei 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 = 11 in una dichiarazione di funzione è più simile a x !== undefined ? x : 11 x !== undefined ? x : 11 rispetto all'idioma molto più comune x || 11 x || 11

Espressioni valore predefinito

Function valori predefiniti delle Function possono essere più di semplici valori come 31; possono essere qualsiasi espressione valida, anche una 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 di valore di default vengono ponderate, 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 di default può anche essere una chiamata di espressioni di funzione inline, comunemente denominata espressione di una funzione (IIFE) Invoked Function (IIFE) :

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

quella soluzione è lavoro per me in js:

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

Basta usare un confronto esplicito con undefined.

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

Essendo uno sviluppatore C ++ di lunga data (Rookie to web development :)), quando ho incontrato per la prima volta questa situazione, ho eseguito l’assegnazione dei parametri nella definizione della funzione, come indicato nella domanda, come segue.

 function myfunc(a,b=10) 

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

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

L’intenzione di questa risposta non è 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.

Consiglio vivamente la massima caucanvas quando si utilizzano i valori dei parametri predefiniti in javascript. Spesso crea bug quando usato in combinazione con funzioni di ordine superiore come forEach , map e reduce . Ad esempio, considera questa riga di codice:

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

parseInt ha una function parseInt(s, [ secondo parametro opzionale function parseInt(s, [ radix =10]) ma parseInt mapping delle chiamate parseInt con tre argomenti: ( elemento , indice e matrice ).

Ti suggerisco di separare i parametri richiesti dai tuoi argomenti di valore facoltativi / predefiniti. Se la tua funzione richiede 1,2 o 3 parametri richiesti per i quali nessun valore predefinito ha senso, rendili parametri posizionali alla funzione, tutti i parametri facoltativi dovrebbero seguire come attributi con nome di un singolo object. Se la tua funzione richiede 4 o più, forse ha più senso fornire tutti gli argomenti tramite gli attributi di un singolo parametro object.

Nel tuo caso ti suggerirei di scrivere la funzione deleteFile in questo modo:

 // 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 = false } = options || {}; // if null 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); 

Come aggiornamento … con ECMAScript 6 puoi FINALMENTE impostare valori predefiniti nelle dichiarazioni dei parametri di funzione in questo modo:

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

Come riferito da – http://es6-features.org/#DefaultParameterValues

Per chiunque sia interessato a far funzionare il codice in Microsoft Edge, non utilizzare i parametri di default.

 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

Secondo la syntax

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

puoi definire il valore predefinito dei parametri formali. e anche controllare il valore non definito usando la funzione typeof .

 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!!! 
 function throwIfNoValue() { throw new Error('Missing argument'); } function foo(argValue = throwIfNoValue()) { return argValue ; } 

Usalo se vuoi usare la più ECMA6 syntax ECMA6 :

 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 

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

 function test (foo = 1, bar = 2) { console.log(foo, bar); } test(5); // foo gets overwritten, bar remains default parameter 

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


ES5: La maggior parte delle risposte fornite non sono abbastanza buone per me perché ci sono occasioni in cui potrei dover passare valori falsi come 0 , null e undefined in una funzione. Per determinare se un parametro non è definito perché quello è il valore che ho passato invece di undefined perché non è stato definito affatto lo faccio:

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

Sì, funzionerà in Javascript. Puoi anche farlo:

 function func(a=10,b=20) { alert (a+' and '+b); } func(); // Result: 10 and 20 func(12); // Result: 12 and 20 func(22,25); // Result: 22 and 25