Установите значение параметра по умолчанию для функции JavaScript

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

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

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

function read_file(file, delete_after = false) {
  // Code
}
21.05.2009 20:07:17
26 ОТВЕТОВ
РЕШЕНИЕ

Начиная с 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
    ···
}

До ES2015 ,

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

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}
3276
17.05.2019 04:38:09
Вы также можете инкапсулировать это как таковое: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }и затем вы можете назвать это какa = defaultFor(a, 42);
Camilo Martin 2.09.2012 05:56:31
@SiPlus, и вы бесплатно получаете дополнительные ошибки ссылок при попытке использовать undefinedобъекты: p Даже если он может работать с некоторыми браузерами и может работать быстрее, nullон все еще является объектом и undefinedявляется ссылкой на примитивный тип, который пытается сказать, что существует здесь ничего нет, даже нет null. Смотрите здесь, оба случая в двух словах: JavaScript / Reference / Global_Objects / undefined .
Sampo Sarrala - codidact.org 3.11.2012 01:29:26
если вы сверяете со свойством объекта, то typeofэто избыточно. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }Это не приведет к ошибкам ссылки и является кратким.
Dziamid 17.05.2013 11:06:12
Я знаю, что это действительно незначительно, но мне не нравится, как вы назначаете a = aи b = bкогда эти параметры не являются неопределенными. Кроме того, этот троичный оператор с немного сложным условием может быть трудно читать для будущих сопровождающих. Я бы предпочел следующий синтаксис: if (typeof a == 'undefined') a = 42- нет ненужных назначений, плюс немного легче для чтения.
Daddy32 9.12.2014 15:31:57
Есть ли причина использовать typeof? Казалось бы, проще сделать a === undefined. Кроме того, в этом случае вы получите ошибку ссылки, если ошибетесь, undefinedа не поместите ее в строку.
Abe Voelker 21.05.2015 22:04:57
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

Это присваивает delete_afterзначение, delete_afterесли оно не является ложным значением, в противном случае оно присваивает строку "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" }); 
595
9.01.2018 10:30:20
Я нахожу это недостаточным, потому что я могу перейти в ложь.
Tom Ritter 21.05.2009 20:11:19
Я считаю, что это подходит для большинства ситуаций
Russ Cam 21.05.2009 20:16:14
Поскольку это не работает для ложных значений, это может создать кошмар обслуживания. Кусок кода, который всегда был передан истинными значениями раньше и внезапно завершается сбоем, потому что ложный код передается, вероятно, следует избегать, если доступен более надежный подход.
jinglesthula 31.10.2012 20:34:24
Почему в этом случае delete_afterне получается логический результат выражения delete_after || "my default value"?
xbonez 28.11.2012 05:56:25
или вы можете просто установить значение по умолчанию для значения Falsey - которое в любом случае обычно является хорошим значением по умолчанию (например, false для bools, пустая строка для строк, 0 для чисел и т. д.) - в этом случае не имеет значения, что было прошел.
Mark Brackett 27.03.2016 01:33:05

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

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

function myFunc(x) {
  x = pick(x, 'my default');
} 
148
21.05.2009 20:18:46
Обновление: если вы уже используете underscore.js, я нахожу его еще лучше _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. Использование глобального пространства имен, как показано в этом ответе, многими считается плохой практикой. Вы также можете рассмотреть возможность использования собственной утилиты для этой общей задачи (например, util.default(arg, "defaul value")если вы не хотите использовать подчеркивание, но я в основном заканчиваю тем, что рано или поздно использую подчеркивание, так или иначе, нет смысла заново изобретать колесо).
andersand 15.08.2014 20:12:02
Я действительно рекомендую этот, я использую его и называю его «por», что означает «параметр или»
super 21.04.2015 16:59:19
Не говорите typeof arg == 'undefined', вместо этого говорите arg === undefined
OsamaBinLogin 20.10.2015 15:06:51
@OsamaBinLogin то, что вы говорите, верно для текущего JS - старый тест сохраняется, потому что в некоторых браузерах раньше можно было перезаписать его undefinedдругим значением, что привело к сбою теста.
Alnitak 16.11.2015 11:34:59
@Alnitak: все еще возможно переопределить undefined. Так что это все еще хорошая идея для использования typeofи 'undefined'.
L S 14.06.2017 20:27:41

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

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

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

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

63
1.06.2015 20:43:06
ECMAScript 6 Полагаю ... (я бы исправил сам, но не могу внести изменения <6 символов)
Zac 1.06.2015 20:15:17
В ожидании браузера любой получить ECMAScript 6
Adriano Resende 8.07.2015 13:05:41
Что бы Вавилон перенес это?
harryg 9.07.2015 11:31:50
Felix Kling 9.07.2015 13:22:35
Вот таблица совместимости для ES6 kangax.github.io/compat-table/es6/#default_function_parameters. К сожалению, этот синтаксис пока не поддерживается .
freemanoid 9.07.2015 19:03:14

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

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

f(1) === 50

На что ссылается - http://es6-features.org/#DefaultParameterValues

9
6.10.2015 16:16:21
Этот ответ бесполезен, потому что он дубликат
user 6.11.2015 00:48:29

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

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}
10
16.11.2015 07:34:34

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

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}
12
16.11.2015 11:29:34
Что будет, если delete_afterесть 0или null? Это не будет работать правильно для этих случаев.
Dmitri Pavlutin 20.12.2015 09:33:37
@StephanBijzitter это было бы верно только в некоторых случаях. Но если вы хотите, чтобы только значения по умолчанию сбрасывали значения, это не сработало, потому что 0 или ноль! === false.
Rutrus 1.02.2017 10:13:12
@Rutrus: Я ничего не понимаю, что вы только что сказали.
Stephan Bijzitter 1.02.2017 10:21:07
Как насчет delete_after = delete_after === undefined ? false : delete_after?
aashah7 28.04.2017 03:50:54

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

function myfunc(a,b=10)

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

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

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

8
19.05.2016 06:40:08
Назначение в определении функции также не работает в IE 11, который является самой последней версией IE для Windows 8.1.
DiMono 19.07.2016 02:52:54
Если кому-то интересно, function myfunc(a,b=10)есть ли синтаксис ES6, в других ответах есть ссылки на таблицы совместимости.
gcampbell 18.09.2016 09:00:01

Да, это будет работать в Javascript. Вы также можете сделать это:

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
-3
19.07.2016 11:59:31
Это в настоящее время не переносимо ... IE ... developer.mozilla.org/en/docs/Web/JavaScript/Reference/… (И это дублирующий ответ ...)
Gert van den Berg 11.05.2017 08:34:59

Всем, кто заинтересован в том, чтобы этот код работал в Microsoft Edge, не используйте значения по умолчанию в параметрах функций.

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

В этом примере Edge выдаст ошибку «Expecting ')'»

Чтобы обойти это использование

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

По состоянию на 08 августа 2016 года это все еще проблема

7
23.09.2016 20:15:38

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

С 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
27
15.10.2016 17:58:14

Согласно синтаксису

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

Вы можете определить значение по умолчанию формальных параметров. а также проверьте неопределенное значение с помощью функции typeof .

4
15.10.2017 20:40:50

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

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

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

Я предлагаю вам отделить необходимые параметры от необязательных / значений по умолчанию. Если ваша функция принимает 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);

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

9
28.01.2019 01:59:40
Это «лучшее решение» совершенно нечитаемо. Я бы порекомендовал проверить тип переменной как typeof deleteAfter === 'bool'и бросить исключение в противном случае. Плюс в случае использования таких методов, как map / foreach и т. Д., Просто используйте их с осторожностью и оберните вызываемые функции анонимной функцией. ['1', '2', '3'].map((value) => {read_file(value);})
instead 26.01.2019 17:36:50
Неплохо подмечено. Я пытался избежать использования библиотек в моем фрагменте кода, но эта идиома довольно грязная в чистом JavaScript. Лично я бы использовал getметод Лодаша для получения deleteAfter. Бросок исключения, если typeof 'deleteAfter' !== 'bool'это также может быть хорошей разумной мерой. Мне не нравится разрабатывать методы, которые требуют от вызывающего абонента "проявлять осторожность". Ответственность лежит на функции, а не на вызывающем абоненте. Конечное поведение должно следовать принципу наименьшего удивления.
Doug Coburn 26.01.2019 18:18:13
Я согласен, этот метод не должен быть написан так, как его вызов может нарушить его поведение. Но имейте в виду, что функция похожа на модель, а вызывающая сторона - на контроллер. Модель должна позаботиться об обработке данных. Функция (метод) должна ожидать, что данные могут быть переданы неверным образом и обработать их. Вот почему проверка типа параметра плюс выдача исключения - лучший способ. Хотя это сложнее. Но все же это может спасти Вас от царапин на голове и продолжать спрашивать ... ПОЧЕМУ ЭТО НЕ РАБОТАЕТ ?! а потом ... ПОЧЕМУ ЭТО РАБОТАЕТ ?!
instead 26.01.2019 23:52:52
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
8.06.2018 08:55:11

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

Здесь foo () - это функция, у которой есть параметр с именем argValue. Если мы ничего не передадим в вызов функции здесь, то будет вызвана функция throwIfNoValue () и возвращенный результат будет присвоен единственному аргументу argValue. Таким образом, вызов функции может использоваться как параметр по умолчанию. Что делает код более простым и читабельным.

Этот пример был взят отсюда

3
1.07.2018 08:50:53

Используйте это, если вы хотите использовать последний 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

Это называется default function parameters. Это позволяет формальным параметрам быть инициализированными со значениями по умолчанию, если не передано значение или undefined. ПРИМЕЧАНИЕ . Он не будет работать с Internet Explorer или более старыми браузерами.

Для максимально возможной совместимости используйте это:

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

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

4
5.07.2018 11:54:50
ПРИМЕЧАНИЕ: как говорит @BlackBeard, функция (param = value) не будет работать с IE. Используйте совместимую версию.
MagicLAMP 16.11.2018 02:31:21

Если вы используете, ES6+вы можете установить параметры по умолчанию следующим образом:

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

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

Если вам нужен ES5синтаксис, вы можете сделать это следующим образом:

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

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

В приведенном выше синтаксисе используется ORоператор. ORОператор всегда возвращает первое значение , если это может быть преобразовано в trueслучае не возвращает righthandside значения. Когда функция вызывается без соответствующего аргумента, переменная параметра ( barв нашем примере) устанавливается undefinedна движок JS. undefinedЗатем преобразуется в false и, таким образом, ORоператор возвращает значение 0.

3
8.08.2018 15:48:37

ES6: Как уже упоминалось в большинстве ответов, в ES6 вы можете просто инициализировать параметр вместе со значением.


ES5: Большинство из приведенных ответов не достаточно хороши для меня, потому что бывают случаи, когда мне приходится передавать ложные значения, такие как 0, nullи undefinedфункции. Чтобы определить, является ли параметр неопределенным, потому что это значение, которое я передал вместо неопределенного из-за того, что оно вообще не было определено, я делаю это:

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}
4
12.08.2018 05:26:12
def read_file(file, delete_after = false)
  # code
end

Следующий код может работать в этой ситуации, включая ECMAScript 6 (ES6), а также более ранние версии.

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

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

0
24.09.2018 23:02:55

Да, это упоминается как параметр по умолчанию

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

Синтаксис:

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

Описание:

Параметры функций по умолчанию имеют значение undefined Однако в ситуациях может быть полезно установить другое значение по умолчанию. Здесь параметры по умолчанию могут помочь.

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

При использовании параметров по умолчанию в ES2015 проверка в теле функции больше не требуется. Теперь вы можете просто поместить значение по умолчанию в заголовок функции.

Пример различий:

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

Различные примеры синтаксиса:

Заполнение не определено против других ложных значений:

Даже если значение установлено явно при вызове, значение аргумента num является значением по умолчанию.

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)

Оценивается во время разговора:

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

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

Параметры по умолчанию доступны для последующих параметров по умолчанию:

Уже найденные параметры доступны для последующих параметров по умолчанию

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

Функции, определенные внутри тела функции:

Представлено в Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30). Функции, объявленные в теле функции, нельзя ссылать в параметрах по умолчанию и генерировать ReferenceError (в настоящее время TypeError в SpiderMonkey, см. Ошибку 1022967). Параметры по умолчанию всегда выполняются в первую очередь, объявления функций внутри тела функции оцениваются позже.

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

Параметры без значений по умолчанию после параметров по умолчанию:

До Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) следующий код приводил к ошибке SyntaxError. Это было исправлено в баге 777060 и работает, как и ожидалось, в более поздних версиях. Параметры по-прежнему устанавливаются слева направо, перезаписывая параметры по умолчанию, даже если есть более поздние параметры без значений по умолчанию.

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

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

Разрушенный параметр с присвоением значения по умолчанию:

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

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

f(); // 6
0
27.09.2018 16:56:00

Если по каким - то причинам вы не на ES6 и которые , используя lodashздесь является кратким способом по умолчанию параметров функции с помощью _.defaultToметода:

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>

Который установит значение по умолчанию, если текущее значение равно NaN , null или undefined

2
10.10.2018 07:10:46

Да, использование параметров по умолчанию полностью поддерживается в ES6 :

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

или

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

но до ES5 вы могли бы легко сделать это:

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

Это означает, что, если значение есть, используйте значение, в противном случае, используйте второе значение после ||операции, которая делает то же самое ...

Примечание: также существует большая разница между этими значениями, если вы передадите значение в ES6 на единицу, даже если это будет ложное значение, которое будет заменено новым значением, например, nullили ""... но ES5 будет заменено только одно, если только переданное значение это правда, потому что способ ||работает ...

3
25.01.2019 08:15:51

Просто другой подход для установки параметров по умолчанию - использовать объектную карту аргументов, а не аргументы напрямую. Например,

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

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

Таким образом, аргументы можно легко расширять и не беспокоиться о несоответствии длины аргумента.

0
13.06.2019 09:26:15

Ответ - да. На самом деле, есть много языков, которые поддерживают параметры по умолчанию. Python является одним из них:

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

Хотя это код Python 3 из-за круглых скобок, параметры по умолчанию в функциях также работают в JS.

Например, и в вашем случае:

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

read_file("test.txt");

Но иногда вам не нужны параметры по умолчанию.

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

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

read_file("test.txt");

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

Итак, в заключение, значения параметров по умолчанию могут быть использованы в JS. Но это почти то же самое, что и определение переменной сразу после запуска функции. Однако иногда они все еще очень полезны. Как вы могли заметить, значения параметров по умолчанию занимают на 1 строку кода меньше стандартного способа, который определяет параметр сразу после запуска функции.

РЕДАКТИРОВАТЬ: И это супер важно! Это не будетработать в IE. Смотрите документацию . Так что с IE вы должны использовать метод «определить переменную в верхней части функции». Параметры по умолчанию не будут работать в IE.

-1
9.04.2020 20:44:41

Звуки будущего

В будущем вы сможете «распространять» один объект на другой (в настоящее время по состоянию на 2019 г. НЕ поддерживается Edge !) - демонстрация того, как использовать это для хороших параметров по умолчанию независимо от порядка:

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

Ссылка на MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

... между тем, что Edge поддерживает, это Object.assign () (IE нет, но я очень надеюсь, что мы можем оставить IE позади :))

Точно так же вы могли бы сделать

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

РЕДАКТИРОВАТЬ: Из-за комментариев относительно constопций - проблема с использованием константных опций в остальной части функции на самом деле не в том, что вы не можете сделать это, просто в том, что вы не можете использовать константу в ее собственном объявлении - настроить ввод имени на что-то вроде

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
}
0
16.12.2019 12:59:30
Проблема в том, что вы обычно никогда не хотите этого делать, так как это повторно назначит опции, которые уже определены, но вы можете использовать их с другой переменной, которая была бы допустимой.
frank-dspeed 13.12.2019 13:29:55
function test (options) {/ * Определяются опции, будет выдано сообщение об ошибке, если вы используете const options = {} сейчас * /}
frank-dspeed 13.12.2019 14:19:16
нет, не глобальный, когда вы создаете функцию, и вы передаете в качестве параметров имени аргумента, то внутри параметров функции определяется внутри функции (opt) {} opt определен, вы не можете использовать const opt ​​внутри этой функции, тогда это плохо, потому что вы делаете переназначение переменной, если вы делаете это часто, и похоже, что ваш общий паттерн - это проблема
frank-dspeed 14.12.2019 07:03:41
@ google-frank-dspeed ах, ты имеешь в виду, что ты не можешь сделать function(opt){ const opt = /*some merging*/; }? Это наверняка не сработает, потому что вы бы использовали constпеременную до того, как она была объявлена - вам нужно было бы ее настроить -function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
jave.web 16.12.2019 12:45:19
@ google-frank-dspeed В любом случае, больше новых людей наверняка задумаются об этом, поэтому я добавил код с
jave.web 16.12.2019 13:00:14

Просто, чтобы продемонстрировать мои навыки тоже (смеется), функция выше может быть написана даже без именованных аргументов, как показано ниже:

ES5 и выше

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

ES6 и выше

function foo(...rest) {
    a = typeof rest[0] !== 'undefined' ? a : 42;
    b = typeof rest[1] !== 'undefined' ? b : 'default_b';
    ...
}
0
19.12.2019 08:39:04