Да, это параметр по умолчанию
Параметры функции по умолчанию позволяют инициализировать формальные параметры значениями по умолчанию, если значение не передано или не передано значение.
Синтаксис:
function [name]([param1[ = defaultValue1 ][, ... paramN[ = defaultValueN ]]]) {
statements
}
Описание :
Параметры функций по умолчанию не определены. Однако в некоторых ситуациях может быть полезно установить другое значение по умолчанию. Здесь могут помочь параметры по умолчанию.
В прошлом общая стратегия установки значений по умолчанию заключалась в проверке значений параметров в теле функции и присвоении значения, если они не определены. Если в вызове не указано значение, его значение будет неопределенным. Вам нужно будет установить условную проверку, чтобы убедиться, что параметр не является неопределенным
С параметрами по умолчанию в 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
Вы также можете инкапсулировать его как таковой:
function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }
, а затем вы можете назвать его какa = defaultFor(a, 42);
Это слишком медленно, используйте
a = ((a != null) ? a : 42);
.@SiPlus, то это , а не , больше значение по умолчанию, и нет никакого смысла, кроме быстрого изменения множества значений, передаваемых функциям (, например, использование определенных констант вместо
null
). В основном ваш код переводитnull
в42
. Если в вашем примереa
равноundefined
, тогда он будет оставатьсяundefined
и не получит никакого значения по умолчанию.@Sampo
undefined==null
(но не===null
). Но если вы намеренно передадите в функциюnull
, мой код не будет работать.@SiPlus, и вы получили дополнительные справочные ошибки бесплатно при попытке использовать объекты
undefined
: p Даже несмотря на то, что он может работать с некоторыми браузерами и может быть быстрее,null
все еще является объектом, аundefined
является ссылкой на примитив типа, который пытается сказать, что здесь ничего нет, дажеnull
. См. Здесь оба случая в двух словах: JavaScript / Reference / Global_Objects / undefined.если вы проверяете свойство объекта, то
typeof
является избыточным.function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }
Это не приведет к ошибкам ссылок и является кратким.У меня это не сработало. Если вы не передадите никакого значения, вы не сможете использовать typeof для параметра. Вместо этого вы должны использовать
var === undefined
Я знаю, что это действительно незначительно, но мне не нравится, как вы назначаете
a = a
иb = b
, когда эти параметры не определены. Кроме того, этот тернарный оператор с немного сложным условием может быть трудночитаем будущим специалистам по сопровождению. Я бы предпочел следующий синтаксис:if (typeof a == 'undefined') a = 42
- без ненужных назначений, плюс немного легче читать.Есть ли причина использовать
typeof
? Казалось бы, проще просто сделатьa === undefined
. Кроме того, вы получите справочную ошибку, если вы неправильно написалиundefined
вместо того, чтобы поместить его в строку.И нам не нужно беспокоиться о том, что
a
окажется глобальной переменной, если она не была указана в вызове функции?@AbeVoelker Были некоторые проблемы с тем, что
undefined
не было ключевым словом в старых движках javascript, поэтому вы могли его перезаписать. Вы всегда можете сгенерировать undefined, используяvoid
- например:a = a !== void 0 ? a : "Default";
- это некрасиво, и в любом случае есть что-то в корне неправильное с перезаписью кода undefined.@Sebi Также примерно так это выглядит, когда вы компилируете / обрабатываете функцию TypeScript с параметрами, имеющими значение по умолчанию.
почему бы просто не использовать менее загадочный
if (typeof a === 'undefined') a = 42;
?вы можете использовать
a = a || 42;
это прощеК вашему сведению: MS Edge и IE11 выдают ошибку при присвоении значения по умолчанию, например: function badArg (imOK, imNOT = '') {} - он будет отказываться от = '' - не проверял null, просто удалил его, потому что он на самом деле не было необходимости.
Обратите внимание, что установка значений по умолчанию в объявлении параметра в настоящее время не работает в мобильных Safari или Chrome.
Вы можете просто написать функцию foo (a, b) {a = a || 42; б = б || 'default_b'; ...}
Есть ли причина, по которой вы не используете положительное «если»?
a = typeof a === 'undefined' ? 42 : a;
Я имею в виду===
вместо!==
?Вы должны передать ввод для 2-го параметра или его можно не указывать?
Я предлагаю обновить ваш ответ, чтобы предупредить о проблемах с использованием значений параметров по умолчанию. См. Мой пост ниже: coderhelper.com/questions/894860/…
В соответствии с этим параметры по умолчанию теперь поддерживаются большинством браузеров (включая мобильные), за исключением IE: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… и kangax.github.io/compat-table/es6
Вы также можете использовать присвоение значений по умолчанию с помощью нотации деструктурирующего присвоения
Я нашел это полезным для отладки, когда функция может запускаться несколькими событиями, чтобы иметь параметр передачи аргумента, указывающего, где функция возникла. Пример:
function myFunction(caller = "unspecified") {if (caller !== "unspecified") {console.log("myFunction called by: " + caller);}
, так что если функцияmyFunction("window scroll");
выводит на консольmyFunction called by: window scroll
... может быть неплохо, если вы хотите получить подробную обратную связь в консоли.Только что заметил, что в коде из моего предыдущего поста отсутствует закрывающая скобка. В конце объявления функции должно быть ...
caller);}}
.+1 Эти вопросы и ответы - прекрасный пример того, что большинство разработчиков придут в SO раньше, чем где-либо еще. :)