Defina um valor de parâmetro padrão para uma função JavaScript

2367

Eu gostaria que uma função JavaScript tivesse argumentos opcionais nos quais eu defini um padrão, que são usados ​​se o valor não for definido (e ignorados se o valor for passado). No Ruby, você pode fazer assim:

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

Isso funciona em JavaScript?

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

Respostas:

3298

No ES6 / ES2015 , os parâmetros padrão estão na especificação do idioma.

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

simplesmente funciona.

Referência: Parâmetros Padrão - MDN

Os parâmetros de função padrão permitem que parâmetros formais sejam inicializados com valores padrão se nenhum valor ou indefinido for passado.

Você também pode simular parâmetros nomeados padrão através da desestruturação :

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

Antes do ES2015 ,

Existem várias maneiras, mas esse é o meu método preferido - ele permite que você passe o que quiser, incluindo falso ou nulo. ( typeof null == "object")

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}
Tom Ritter
fonte
216
Você também pode encapsular-lo como tal: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }e então você pode chamá-lo comoa = defaultFor(a, 42);
Camilo Martin
6
O @SiPlus e você obteve erros de referência extras gratuitamente ao tentar usar undefinedobjetos: p Mesmo que funcione com alguns navegadores e possa ser mais rápido, nullainda é um objeto e undefinedé referência ao tipo primitivo que está tentando dizer que há nada aqui, nem mesmo null. Veja aqui os dois casos em poucas palavras: JavaScript / Reference / Global_Objects / undefined .
Sampo Sarrala - codidact.org
9
se você verificar a propriedade de um objeto, typeofserá redundante. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }Isso não gera erros de referência e é conciso.
Dziamid 17/05
10
Eu sei que é muito pequeno, mas não gosto de como você está atribuindo a = ae b = bquando esses parâmetros não são indefinidos. Além disso, esse operador ternário com uma condição um pouco complicada pode ser difícil de ler para futuros mantenedores. Eu preferiria a seguinte sintaxe: if (typeof a == 'undefined') a = 42- nenhuma atribuição desnecessária e um pouco mais fácil de ler.
usar o seguinte comando
12
Existe algum motivo para usar typeof? Parece mais simples de fazer a === undefined. Além disso, dessa forma, você obteria um erro de referência se escrevesse incorretamente undefinedx colocá-lo em uma string.
Abe Voelker
599
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

Isso atribui ao delete_aftervalor de delete_afterse não for um valor falsey, caso contrário, atribui a string "my default here". Para mais detalhes, consulte a pesquisa de Doug Crockford sobre o idioma e a seção Operadores .

Essa abordagem não funciona se você deseja passar em um falsey valor ou seja false, null, undefined, 0ou "". Se você precisar que os valores de falsey sejam passados, precisará usar o método na resposta de Tom Ritter .

Ao lidar com vários parâmetros para uma função, geralmente é útil permitir ao consumidor passar os argumentos dos parâmetros em um objeto e depois mesclar esses valores com um objeto que contém os valores padrão da função

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

usar

// 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" }); 
Russ Cam
fonte
115
Acho isso insuficiente, porque posso passar em falso.
Tom Ritter #
52
Acho que é adequado para a maioria das situações
Russ Cam
50
Por não funcionar com valores falsey, pode criar um pesadelo de manutenção. Um pouco de código que sempre passou por valores reais antes e falha repentinamente porque um código falsa é passado provavelmente deve ser evitado onde houver uma abordagem mais robusta.
jinglesthula
1
Como, nesse caso, delete_afternão obtém o resultado booleano da expressão delete_after || "my default value"?
Xbonez 28/11/2012
3
ou você pode simplesmente usar como padrão um valor falsey - que geralmente é um bom padrão (por exemplo, false para bools, string vazia para strings, 0 para números etc.) - nesse caso, não importa realmente o que foi passou.
Mark Brackett
150

Acho que algo simples como esse é muito mais conciso e legível pessoalmente.

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

function myFunc(x) {
  x = pick(x, 'my default');
} 
TJ L
fonte
6
Atualização: se você já usa o underscore.js , acho ainda melhor usá-lo _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. O uso do namespace global, como mostrado nesta resposta, é considerado por muitos uma prática ruim. Você também pode considerar util.default(arg, "defaul value")usar seu próprio utilitário para esta tarefa comum (por exemplo ) se não quiser usar sublinhado, mas eu acabo usando sublinhado mais cedo ou mais tarde, de qualquer maneira, não adianta reinventar a roda.
precisa saber é o seguinte
2
Na verdade, eu recomendo este, eu usá-lo e chamá-lo "por" que significa "parâmetro ou"
Super
2
Não diga typeof arg == 'indefinido', em vez dizer arg === indefinido
OsamaBinLogin
3
@OsamaBinLogin, o que você diz é correto para o JS atual - o teste mais antigo persiste porque em alguns navegadores era possível substituir undefinedcom algum outro valor, causando falha no teste.
Alnitak
2
@ Alnitak: Ainda é possível substituir undefined. Portanto, ainda é uma boa ideia usar typeofe 'undefined'.
LS
63

No ECMAScript 6, você poderá escrever exatamente o que possui:

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

Isso será definido delete_aftercomo falsese não estiver presente ou undefined. Você pode usar recursos ES6 como este hoje com transpilers como Babel .

Consulte o artigo MDN para obter mais informações .

Felix Kling
fonte
1
ECMAScript 6 suponho ... (eu teria corrigido por mim, mas não posso fazer edições <6 caracteres)
Zac
1
Esperando navegador qualquer obter ECMAScript 6
Adriano Resende
1
Para o que Babel traduzia isso?
9119 harryg
2
@harryg: babeljs.io/repl/…
Felix Kling
2
Aqui está a tabela de compatibilidade para ES6 kangax.github.io/compat-table/es6/#default_function_parameters Infelizmente, essa sintaxe ainda não é suportada .
freemanoid
27

Valores de parâmetro padrão

Com o ES6, você pode fazer um dos idiomas mais comuns em JavaScriptrelação à configuração de um valor padrão para um parâmetro de função. A maneira como fizemos isso por anos deve parecer bastante familiar:

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

Esse padrão é mais usado, mas é perigoso quando passamos valores como

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

Por quê? Porque o 0 is falsy, e então o x || 11 results in 11, não o diretamente passado em 0. Para corrigir esse problema, algumas pessoas escrevem o cheque de maneira mais detalhada assim:

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

agora podemos examinar uma boa sintaxe útil adicionada a partir de ES6para simplificar a atribuição de valores padrão a argumentos ausentes:

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 em uma declaração de função é mais como x !== undefined ? x : 11 o idioma muito mais comumx || 11

Expressões de valor padrão

Functionvalores padrão podem ser mais do que valores simples como 31; eles podem ser qualquer expressão válida, até um 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

Como você pode ver, as expressões de valor padrão são avaliadas com preguiça, o que significa que só são executadas se e quando são necessárias - ou seja, quando o argumento de um parâmetro é omitido ou indefinido.

Uma expressão de valor padrão pode até ser uma chamada de expressão de função embutida - geralmente chamada de Expressão de Função Invocada Imediatamente (IIFE):

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

essa solução é trabalho para mim em js:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}
Takács Zsolt
fonte
4
O que acontece se delete_afteré 0ou null? Não funcionará corretamente para esses casos.
Dmitri Pavlutin
@StephanBijzitter só seria verdade em alguns casos. Mas se você deseja que apenas os valores padrão desabilitem valores, isso não funcionou, porque 0 ou nulo! === false.
Rutrus
@Rutrus: Eu não entendo nada do que você acabou de dizer.
Stephan Bijzitter
Que tal delete_after = delete_after === undefined ? false : delete_after?
precisa saber é o seguinte
10

Basta usar uma comparação explícita com indefinido.

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}
Martin Wantke
fonte
10

Eu recomendaria muito cuidado ao usar valores de parâmetro padrão em javascript. É muitas vezes cria erros quando usado em conjunto com as funções de ordem superior, como forEach, map, e reduce. Por exemplo, considere esta linha de código:

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

parseInt possui um segundo parâmetro opcional function parseInt(s, [radix,=10]) mas mapeia as chamadas parseIntcom três argumentos: ( elemento , índice e matriz ).

Sugiro que você separe os parâmetros necessários dos argumentos com valor opcional / padrão. Se sua função usa 1,2 ou 3 parâmetros necessários para os quais nenhum valor padrão faz sentido, torne-os parâmetros posicionais para a função, quaisquer parâmetros opcionais devem seguir como atributos nomeados de um único objeto. Se sua função precisar de 4 ou mais, talvez faça mais sentido fornecer todos os argumentos por meio de atributos de um único parâmetro de objeto.

No seu caso, sugiro que você escreva sua função deleteFile assim: ( editada instead pelos comentários ) ...

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

A execução do trecho acima ilustra os perigos ocultos por trás dos valores de argumento padrão para parâmetros não utilizados.

Doug Coburn
fonte
1
Esta "melhor solução" é bastante ilegível. Eu preferiria verificar o tipo de variável like typeof deleteAfter === 'bool'e lançar Exception caso contrário. Além disso, no caso de usar métodos como map / foreach etc., use-os com cuidado e agrupe as funções chamadas com função anônima. ['1', '2', '3'].map((value) => {read_file(value);})
vez disso
Este é um bom ponto. Eu estava tentando evitar o uso de bibliotecas no meu snippet de código, mas esse idioma é bastante confuso em javascript puro. Pessoalmente, eu usaria o getmétodo do lodash para recuperar deleteAfter. Lançar uma exceção typeof 'deleteAfter' !== 'bool'também pode ser uma boa medida prudente. Não gosto de criar métodos que exijam que o chamador "tenha cuidado". Cuidado é responsabilidade da função, não do chamador. O comportamento final deve seguir o princípio da menor surpresa.
Doug Coburn
Eu concordo que esse método não deve ser escrito da maneira, que chamá-lo, pode quebrar seu comportamento. Mas lembre-se de que a função é como modelo e o chamador é como controlador. O modelo deve cuidar do processamento de dados. A função (método) deve esperar que os dados possam ser transmitidos de maneira errada e manipulá-los. É por isso que verificar o tipo de parâmetro e lançar a exceção é o melhor caminho. Mesmo que seja mais complexo. Mas ainda assim pode salvá-lo de coçar a cabeça e continuar perguntando ... POR QUE NÃO ESTÁ FUNCIONANDO ?! e então ... POR QUE ESTÁ FUNCIONANDO ?!
vez
9

Como uma atualização ... com o ECMAScript 6, você pode FINALMENTE definir valores padrão nas declarações de parâmetros de função da seguinte forma:

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

f(1) === 50

Conforme referenciado por - http://es6-features.org/#DefaultParameterValues

zillaofthegods
fonte
11
Esta resposta não é útil porque é uma duplicata
user
8

como desenvolvedor C ++ há muito tempo (iniciante no desenvolvimento da Web :)), quando me deparei com essa situação, fiz a atribuição de parâmetros na definição de função, como mencionado na pergunta, como segue.

function myfunc(a,b=10)

Mas lembre-se de que ele não funciona de maneira consistente nos navegadores. Para mim, funcionou no chrome no meu desktop, mas não funcionou no chrome no android. A opção mais segura, como muitos mencionaram acima, é -

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

A intenção desta resposta não é repetir as mesmas soluções, o que outros já mencionaram, mas informar que a atribuição de parâmetros na definição de função pode funcionar em alguns navegadores, mas não depende dela.

vivek
fonte
3
A atribuição na definição da função também não funciona no IE 11, que é a versão mais atual do IE para Windows 8.1.
DiMono 19/07
1
Caso alguém esteja se perguntando, function myfunc(a,b=10)é a sintaxe do ES6, há links para tabelas de compatibilidade em outras respostas.
gcampbell 18/09/16
7

Para qualquer pessoa interessada em que o código funcione no Microsoft Edge, não use padrões nos parâmetros de função.

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

Nesse exemplo, o Edge lançará um erro "Esperando ')'"

Para contornar esse uso

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

Em 08 de agosto de 2016, este ainda é um problema

Steven Johnston
fonte
4

Conforme a sintaxe

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

você pode definir o valor padrão dos parâmetros formais. e também verifique o valor indefinido usando a função typeof .

Sachin Kumar
fonte
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!!!
Tính Ngô Quang
fonte
4

Use isso se desejar usar a ECMA6sintaxe mais 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

É chamado default function parameters. Permite que parâmetros formais sejam inicializados com valores padrão se nenhum valor ou indefinido for passado. NOTA : Ele não funciona com o Internet Explorer ou navegadores mais antigos.

Para máxima compatibilidade possível, use o seguinte:

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

Ambas as funções têm exatamente o mesmo comportamento de cada um desses exemplos, com base no fato de que a variável de parâmetro será undefinedse nenhum valor de parâmetro foi passado ao chamar essa função.

Barba Negra
fonte
NOTA: como o @BlackBeard diz, a função (param = value) NÃO funcionará com o IE. Use a versão compatível.
MagicLAMP
4

ES6: Como já mencionado na maioria das respostas, no ES6, você pode simplesmente inicializar um parâmetro junto com um valor.


ES5: A maioria das respostas dadas não são bons o suficiente para mim, porque há ocasiões em que eu possa ter de passar valores Falsey tais como 0, nulle undefinedpara uma função. Para determinar se um parâmetro é indefinido porque esse é o valor que eu passei em vez de indefinido por não ter sido definido de maneira alguma, faço isso:

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

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

Aqui foo () é uma função que possui um parâmetro chamado argValue. Se não passarmos nada na chamada de função aqui, a função throwIfNoValue () será chamada e o resultado retornado será atribuído ao único argumento argValue. É assim que uma chamada de função pode ser usada como parâmetro padrão. O que torna o código mais simplificado e legível.

Este exemplo foi retirado daqui

dutta
fonte
3

Se você estiver usando, ES6+poderá definir parâmetros padrão da seguinte maneira:

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

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

Se você precisar de ES5sintaxe, poderá fazê-lo da seguinte maneira:

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

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

Na sintaxe acima, o ORoperador é usado. O ORoperador sempre retorna o primeiro valor, se puder ser convertido em, truecaso contrário, ele retornará o valor do lado direito. Quando a função é chamada sem argumento correspondente, a variável de parâmetro ( barem nosso exemplo) é configurada undefinedpelo mecanismo JS. undefinedÉ então convertido para false e, assim, o ORoperador retorna o valor 0.

Willem van der Veen
fonte
3

Sim, o uso de parâmetros padrão é totalmente suportado no ES6 :

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

ou

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

mas antes no ES5, você poderia fazer isso facilmente:

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

O que significa que, se o valor estiver lá, use o valor, caso contrário, use o segundo valor após || operação, que faz a mesma coisa ...

Nota: também há uma grande diferença entre aqueles que se você passar um valor para o ES6, mesmo que o valor seja falso, que será substituído por um novo valor, algo como nullou ""... mas o ES5 apenas será substituído se apenas o valor passado é verdade, é porque a maneira de ||trabalhar ...

Alireza
fonte
2

Se, por algum motivo, você não estiver no ES6 e estiver usando lodashaqui, é uma maneira concisa de padronizar os parâmetros de função por meio do _.defaultTométodo:

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>

O que definirá o padrão se o valor atual for NaN , nulo ou indefinido

Akrion
fonte
1

Sons do futuro

No futuro, você poderá "espalhar" um objeto para outro (atualmente a partir de 2019 NÃO é suportado pelo Edge !) - demonstração de como usá-lo para boas opções padrão, independentemente da ordem:

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

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

... enquanto isso, o Edge DOES suporta Object.assign () (o IE não, mas realmente espero que possamos deixar o IE para trás :))

Da mesma forma, você poderia fazer

    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: Devido aos comentários sobre as constopções - o problema de usar opções constantes no restante da função não é que você não possa fazer isso, é apenas que não pode usar a variável constante em sua própria declaração - você teria para ajustar a nomeação de entrada para algo como

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
}
jave.web
fonte
O problema é que você normalmente nunca deseja fazer isso, pois isso irá atribuir opções que já estão definidas, mas você pode usá-lo com outro var que seria legítimo.
frank-dspeed
teste de função (opções) {/ * Opções é definido ele irá lançar um erro se você usar as opções de const = {} agora * /}
frank-dspeed
não não global quando você cria uma função e passa como opções de nome do argumento, então dentro das opções da função é definida dentro da função (opt) {} opt é definida, você não pode usar const opt ​​dentro dessa função; isso é ruim porque você faz redesignação variável se você fizer isso muitas vezes e parece que o seu padrão geral esta é uma questão
frank-dspeed
@ ah-google-frank-dspeed, você quer dizer que não pode fazer function(opt){ const opt = /*some merging*/; }? Isso com certeza não vai funcionar porque você usaria constvariável antes de ter sido declarada - você teria que ajustar -function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
jave.web
@ google-frank-dspeed de qualquer maneira mais novas pessoas provavelmente irá perguntar sobre isso, então eu adicionei o how-to código para editar :) por isso obrigado por apontar isso para os outros :)
jave.web
1

Apenas para mostrar minhas habilidades também (lol), a função acima pode ser escrita mesmo sem ter nomeado argumentos como abaixo:

ES5 e acima

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

ES6 e acima

function foo(...rest) {
    a = typeof rest[0] !== 'undefined' ? a : 42;
    b = typeof rest[1] !== 'undefined' ? b : 'default_b';
    ...
}
Shivang Gupta
fonte
0
def read_file(file, delete_after = false)
  # code
end

O código a seguir pode funcionar nessa situação, incluindo o ECMAScript 6 (ES6), bem como as versões anteriores.

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

como o valor padrão em idiomas funciona quando o valor do parâmetro da função é ignorado ao chamar, no JavaScript ele é atribuído como indefinido . Essa abordagem não parece atraente programaticamente, mas tem compatibilidade com versões anteriores .

Muhammad Rizwan
fonte
0

Sim, isso é chamado de parâmetro padrão

Os parâmetros de função padrão permitem que parâmetros formais sejam inicializados com valores padrão se nenhum valor ou indefinido for passado.

Sintaxe:

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

Descrição:

Parâmetros de funções padrão para indefinidos No entanto, em situações, pode ser útil definir um valor padrão diferente. É aqui que os parâmetros padrão podem ajudar.

No passado, a estratégia geral para definir padrões era testar valores de parâmetros no corpo da função e atribuir um valor se eles não estiverem definidos. Se nenhum valor for fornecido na chamada, seu valor será indefinido. Você precisaria definir uma verificação condicional para garantir que o parâmetro não seja indefinido

Com os parâmetros padrão no ES2015, a verificação no corpo da função não é mais necessária. Agora você pode simplesmente colocar um valor padrão na cabeça da função.

Exemplo das diferenças:

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

Exemplos de sintaxe diferentes:

Preenchimento indefinido vs outros valores falsos:

Mesmo se o valor for definido explicitamente ao chamar, o valor do argumento num será o padrão.

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)

Avaliada no momento da chamada:

O argumento padrão é avaliado no momento da chamada, portanto, diferente de outros idiomas, um novo objeto é criado toda vez que a função é chamada.

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

Os parâmetros padrão estão disponíveis para os parâmetros padrão posteriores:

Os parâmetros já encontrados estão disponíveis para parâmetros padrão posteriores

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

Funções definidas dentro do corpo da função:

Introduzido no Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30). As funções declaradas no corpo da função não podem ser consultadas dentro dos parâmetros padrão e geram um ReferenceError (atualmente um TypeError no SpiderMonkey, consulte o bug 1022967). Os parâmetros padrão são sempre executados primeiro, as declarações de funções dentro do corpo da função são avaliadas posteriormente.

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

Parâmetros sem padrões após os parâmetros padrão:

Antes do Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2), o código a seguir resultava em um SyntaxError. Isso foi corrigido no bug 777060 e funciona como esperado em versões posteriores. Os parâmetros ainda são definidos da esquerda para a direita, substituindo os parâmetros padrão, mesmo se houver parâmetros posteriores sem padrões.

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

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

Parâmetro destruído com atribuição de valor padrão:

Você pode usar a atribuição de valor padrão com a notação de atribuição de desestruturação

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

f(); // 6
Esewalson
fonte
0

Uma abordagem diferente para definir parâmetros padrão é usar o mapa de objetos de argumentos, em vez de argumentos diretamente. Por exemplo,

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

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

Dessa forma, é fácil estender os argumentos e não se preocupar com a incompatibilidade de comprimento dos argumentos.

Aman Pandey
fonte
-1

A resposta é sim. De fato, existem muitos idiomas que suportam parâmetros padrão. Python é um deles:

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

Embora esse seja o código Python 3 devido aos parênteses, os parâmetros padrão nas funções também funcionam em JS.

Por exemplo, e no seu caso:

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

read_file("test.txt");

Mas às vezes você realmente não precisa de parâmetros padrão.

Você pode apenas definir a variável logo após o início da função, assim:

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

read_file("test.txt");

Nos dois exemplos, ele retorna a mesma coisa. Mas, às vezes, eles realmente podem ser úteis, como em projetos muito avançados.

Portanto, em conclusão, os valores padrão dos parâmetros podem ser usados ​​em JS. Mas é quase o mesmo que definir uma variável logo após o início da função. No entanto, às vezes eles ainda são muito úteis. Como você deve ter notado, os valores padrão dos parâmetros têm 1 linha a menos de código do que a maneira padrão que define o parâmetro logo após o início da função.

EDIT: E isso é super importante! Isso não funcionará no IE. Veja a documentação . Portanto, com o IE, você deve usar o método "definir variável no topo da função". Parâmetros padrão não funcionarão no IE.

zixuan
fonte
-3

Sim, isso funcionará em Javascript. Você também pode fazer isso:

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
Muhammad Awais
fonte
2
No momento não é portátil ... IE ... developer.mozilla.org/en/docs/Web/JavaScript/Reference/... (E é uma resposta duplicada ...)
Gert van den Berg