Вопрос: Задайте значение параметра по умолчанию для функции JavaScript


Я хотел бы, чтобы функция JavaScript имела необязательные аргументы, для которых я устанавливал значение по умолчанию, которое используется, если значение не определено. В Ruby вы можете сделать это следующим образом:

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

Это работает в JavaScript?

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

1989


источник


Ответы:


Из ES6 / ES2015 параметры по умолчанию указаны в спецификации языка.

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

просто работает.

Справка: Параметры по умолчанию - MDN

Параметры функции по умолчанию позволяют инициализировать формальные параметры со значениями по умолчанию, если неважно или не определено передается.

Вы также можете моделировать по умолчанию названный параметров путем деструктурирования :

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

Есть много способов, но это мой предпочтительный метод - он позволяет вам передавать все, что вы хотите, в том числе false или null. ( typeof null == "object")

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

2904



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

Это присваивает delete_afterзначение delete_afterесли это не falsey значение в противном случае назначает строку "my default here", Для более подробной информации, проверьте Исследование Дуга Крокфорда по языку и ознакомление с разделом «Операторы» ,

Этот подход не работает, если вы хотите falsey значение, т.е. false, null, undefined, 0или "", Если вам требуется falsey значения, которые должны быть переданы вам, необходимо будет использовать метод в Ответ Тома Риттера ,

При работе с несколькими параметрами функции часто бывает полезно разрешить потребителю передавать аргументы параметров в объекте, а затем сливаться эти значения с объектом, который содержит значения по умолчанию для функции

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

использовать

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

555



Я нахожу что-то простое, как это, чтобы быть более сжатым и читаемым лично.

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

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

136



В ECMAScript 6 вы действительно сможете написать именно то, что у вас есть:

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

Это установит delete_afterв falseесли он отсутствует или undefined, Вы можете использовать ES6-функции, подобные этим сегодня, с транспилерами, такими как галдеж ,

См. Статью MDN для получения дополнительной информации ,


51



Значения параметров по умолчанию

С ES6 вы можете сделать, возможно, одну из самых распространенных идиом в JavaScriptотносится к установке значения по умолчанию для параметра функции. То, как мы это делали в течение многих лет, должно выглядеть вполне знакомым:

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

Этот шаблон наиболее часто используется, но он опасен, когда мы передаем такие значения, как

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

Зачем? Поскольку 0 is falsy, и поэтому x || 11 results in 11, а не непосредственно передается в 0. Чтобы исправить эту ошибку, некоторые люди вместо этого напишут проверку более подробно:

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

теперь мы можем рассмотреть хороший полезный синтаксис, добавленный с ES6для упрощения присвоения значений по умолчанию отсутствующим аргументам:

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в объявлении функции больше похоже на x !== undefined ? x : 11чем гораздо более распространенная идиома x || 11

Выражения по умолчанию

Functionзначения по умолчанию могут быть больше, чем просто простые значения, такие как 31; они могут быть любым допустимым выражением, даже 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

Как вы можете видеть, выражения значения по умолчанию оцениваются лениво, что означает, что они выполняются только тогда, когда и когда они нужны, то есть когда аргумент параметра опущен или не определен.

Выражение по умолчанию может даже быть вызовом выражения встроенной функции - обычно называемым выражением Вызываемой функции (IIFE):

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

18



that solution is work for me in js:

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

8



Just use an explicit comparison with undefined.

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

6



being a long time C++ developer (Rookie to web development :)), when I first came across this situation, I did the parameter assignment in the function definition, like it is mentioned in the question, as follows.

function myfunc(a,b=10)

But beware that it doesn't work consistently across browsers. For me it worked on chrome on my desktop, but did not work on chrome on android. Safer option, as many have mentioned above is -

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

Intention for this answer is not to repeat the same solutions, what others have already mentioned, but to inform that parameter assignment in the function definition may work on some browsers, but don't rely on it.


5



As an update...with ECMAScript 6 you can FINALLY set default values in function parameter declarations like so:

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

f(1) === 50

As referenced by - http://es6-features.org/#DefaultParameterValues


4



To anyone interested in having there code work in Microsoft Edge, do not use defaults in function parameters.

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

In that example Edge will throw an error "Expecting ')'"

To get around this use

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

As of Aug 08 2016 this is still an issue


4



I would highly recommend extreme caution when using default parameter values in javascript. It often creates bugs when used in conjunction with higher order functions like forEach, map, and reduce. For example, consider this line of code:

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

parseInt has an optional second parameter function parseInt(s, [radix=10]) but map calls parseInt with three arguments: (element, index, and array).

I suggest you separate your required parameters form your optional/default valued arguments. If your function takes 1,2, or 3 required parameters for which no default value makes sense, make them positional parameters to the function, any optional parameters should follow as named attributes of a single object. If your function takes 4 or more, perhaps it makes more sense to supply all arguments via attributes of a single object parameter.

In your case I would suggest you write your deleteFile function like this:

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

Running the above snippet illustrates the dangers lurking behind default argument values for unused parameters.


4



As per the syntax

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

you can define the default value of formal parameters. and also check undefined value by using typeof function.


1