Установите значение параметра по умолчанию для функции JavaScript - PullRequest
2212 голосов
/ 22 мая 2009

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

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

Работает ли это в JavaScript?

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

Ответы [ 23 ]

3140 голосов
/ 22 мая 2009

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

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

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

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

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

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

// 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';
  ...
}
585 голосов
/ 22 мая 2009
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" }); 
144 голосов
/ 22 мая 2009

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

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

function myFunc(x) {
  x = pick(x, 'my default');
} 
61 голосов
/ 29 мая 2015

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

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

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

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

25 голосов
/ 15 октября 2016

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

С 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
11 голосов
/ 16 ноября 2015

это решение для меня работает в js:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}
9 голосов
/ 16 ноября 2015

Просто используйте явное сравнение с неопределенным.

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}
8 голосов
/ 06 октября 2015

В качестве обновления ... с ECMAScript 6 вы можете НАКОНЕЦ установить значения по умолчанию в объявлениях параметров функции следующим образом:

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

f(1) === 50

Как указано - http://es6 -features.org / # DefaultParameterValues ​​

7 голосов
/ 16 октября 2017

Я бы настоятельно рекомендовал соблюдать крайнюю осторожность при использовании значений параметров по умолчанию в javascript. Он часто создает ошибки, когда используется в сочетании с функциями более высокого порядка, такими как forEach, map и reduce. Например, рассмотрим эту строку кода:

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

parseInt имеет необязательный второй параметр function parseInt(s, [ radix =10]), но карта вызывает parseInt с тремя аргументами: ( element , index и массив ).

Я предлагаю вам отделить обязательные параметры от необязательных / значений по умолчанию. Если ваша функция принимает 1,2 или 3 обязательных параметра, для которых значение по умолчанию не имеет смысла, сделайте их позиционными параметрами для функции, любые дополнительные параметры должны следовать как именованные атрибуты одного объекта. Если вашей функции требуется 4 или более, возможно, имеет смысл предоставить все аргументы через атрибуты одного параметра объекта.

В вашем случае я бы предложил вам написать функцию deleteFile следующим образом: ( отредактировано за instead * комментариев ) ...

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

Выполнение приведенного выше фрагмента иллюстрирует опасности, скрывающиеся за значениями аргументов по умолчанию для неиспользуемых параметров.

7 голосов
/ 19 мая 2016

, долгое время являясь разработчиком C ++ (новичок в веб-разработке :)), когда я впервые столкнулся с этой ситуацией, я произвел назначение параметров в определении функции, как это упоминается в вопросе, следующим образом.

function myfunc(a,b=10)

Но учтите, что он не работает согласованно во всех браузерах. У меня это работало на Chrome на моем рабочем столе, но не работало на Chrome на Android. Более безопасный вариант, как многие упоминали выше, -

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

Намерение для этого ответа не состоит в том, чтобы повторить те же решения, которые уже упоминали другие, но чтобы сообщить, что присвоение параметров в определении функции может работать в некоторых браузерах, но не полагаться на это.

...