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

avatar
Tilendor
21 мая 2009 в 20:07
1341251
29
2508

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

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

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

function read_file(file, delete_after = false) {
  // Code
}
Источник

Ответы (29)

avatar
Tom Ritter
21 мая 2009 в 20:10
3448

Начиная с 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';
  ...
}
Camilo Martin
2 сентября 2012 в 05:56
224

Вы также можете инкапсулировать его как таковой: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }, а затем вы можете назвать его как a = defaultFor(a, 42);

Triang3l
28 сентября 2012 в 17:10
3

Это слишком медленно, используйте a = ((a != null) ? a : 42);.

Sampo Sarrala - codidact.org
2 ноября 2012 в 08:29
4

@SiPlus, то это , а не , больше значение по умолчанию, и нет никакого смысла, кроме быстрого изменения множества значений, передаваемых функциям (, например, использование определенных констант вместо null ). В основном ваш код переводит null в 42. Если в вашем примере a равно undefined, тогда он будет оставаться undefined и не получит никакого значения по умолчанию.

Triang3l
2 ноября 2012 в 13:11
2

@Sampo undefined==null (но не ===null). Но если вы намеренно передадите в функцию null, мой код не будет работать.

Sampo Sarrala - codidact.org
3 ноября 2012 в 01:29
7

@SiPlus, и вы получили дополнительные справочные ошибки бесплатно при попытке использовать объекты undefined: p Даже несмотря на то, что он может работать с некоторыми браузерами и может быть быстрее, null все еще является объектом, а undefined является ссылкой на примитив типа, который пытается сказать, что здесь ничего нет, даже null. См. Здесь оба случая в двух словах: JavaScript / Reference / Global_Objects / undefined.

Dziamid
17 мая 2013 в 11:06
10

если вы проверяете свойство объекта, то typeof является избыточным. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; } Это не приведет к ошибкам ссылок и является кратким.

Rick Eyre
19 июля 2013 в 15:14
4

У меня это не сработало. Если вы не передадите никакого значения, вы не сможете использовать typeof для параметра. Вместо этого вы должны использовать var === undefined

Daddy32
9 декабря 2014 в 15:31
12

Я знаю, что это действительно незначительно, но мне не нравится, как вы назначаете a = a и b = b, когда эти параметры не определены. Кроме того, этот тернарный оператор с немного сложным условием может быть трудночитаем будущим специалистам по сопровождению. Я бы предпочел следующий синтаксис: if (typeof a == 'undefined') a = 42 - без ненужных назначений, плюс немного легче читать.

Abe Voelker
21 мая 2015 в 22:04
13

Есть ли причина использовать typeof? Казалось бы, проще просто сделать a === undefined. Кроме того, вы получите справочную ошибку, если вы неправильно написали undefined вместо того, чтобы поместить его в строку.

Riveascore
26 июня 2015 в 18:21
1

И нам не нужно беспокоиться о том, что a окажется глобальной переменной, если она не была указана в вызове функции?

Sebi
27 августа 2015 в 00:51
4

@AbeVoelker Были некоторые проблемы с тем, что undefined не было ключевым словом в старых движках javascript, поэтому вы могли его перезаписать. Вы всегда можете сгенерировать undefined, используя void - например: a = a !== void 0 ? a : "Default"; - это некрасиво, и в любом случае есть что-то в корне неправильное с перезаписью кода undefined.

Sebi
27 августа 2015 в 00:52
1

@Sebi Также примерно так это выглядит, когда вы компилируете / обрабатываете функцию TypeScript с параметрами, имеющими значение по умолчанию.

cregox
24 ноября 2015 в 11:42
4

почему бы просто не использовать менее загадочный if (typeof a === 'undefined') a = 42;?

Diptox
8 января 2016 в 15:36
2

вы можете использовать a = a || 42; это проще

Wes
12 августа 2016 в 18:17
2

К вашему сведению: MS Edge и IE11 выдают ошибку при присвоении значения по умолчанию, например: function badArg (imOK, imNOT = '') {} - он будет отказываться от = '' - не проверял null, просто удалил его, потому что он на самом деле не было необходимости.

bevanb
23 августа 2016 в 18:10
2

Обратите внимание, что установка значений по умолчанию в объявлении параметра в настоящее время не работает в мобильных Safari или Chrome.

Sarath S Nair
30 января 2017 в 04:18
0

Вы можете просто написать функцию foo (a, b) {a = a || 42; б = б || 'default_b'; ...}

Guillaume Vincent
20 июня 2017 в 09:53
0

Есть ли причина, по которой вы не используете положительное «если»? a = typeof a === 'undefined' ? 42 : a; Я имею в виду === вместо !==?

fungusanthrax
6 июля 2017 в 13:57
0

Вы должны передать ввод для 2-го параметра или его можно не указывать?

Doug Coburn
15 октября 2017 в 22:49
0

Я предлагаю обновить ваш ответ, чтобы предупредить о проблемах с использованием значений параметров по умолчанию. См. Мой пост ниже: coderhelper.com/questions/894860/…

KayakinKoder
27 октября 2017 в 01:51
0

В соответствии с этим параметры по умолчанию теперь поддерживаются большинством браузеров (включая мобильные), за исключением IE: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… и kangax.github.io/compat-table/es6

Tanya Gupta
17 февраля 2018 в 19:56
1

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

Mentalist
17 апреля 2019 в 07:00
0

Я нашел это полезным для отладки, когда функция может запускаться несколькими событиями, чтобы иметь параметр передачи аргумента, указывающего, где функция возникла. Пример: function myFunction(caller = "unspecified") {if (caller !== "unspecified") {console.log("myFunction called by: " + caller);}, так что если функция myFunction("window scroll"); выводит на консоль myFunction called by: window scroll ... может быть неплохо, если вы хотите получить подробную обратную связь в консоли.

Mentalist
18 апреля 2019 в 00:28
0

Только что заметил, что в коде из моего предыдущего поста отсутствует закрывающая скобка. В конце объявления функции должно быть ... caller);}}.

Taco タコス
6 ноября 2019 в 01:37
0

+1 Эти вопросы и ответы - прекрасный пример того, что большинство разработчиков придут в SO раньше, чем где-либо еще. :)

avatar
Aftab Amin
26 июля 2021 в 12:12
0
export const getfilesize = (bytes, decimals = 2) => {
    if (bytes === 0){ 
        return '0 Bytes';
    }else{
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];

    }
}
avatar
maxxioso
3 мая 2021 в 18:30
1

Я заметил несколько ответов, в которых упоминалось, что использование параметров по умолчанию не переносимо для других браузеров, но справедливо отметить, что вы можете использовать транспилеры, такие как Babel, для преобразования вашего кода в синтаксис ES5 для браузеров с ограниченной поддержкой для современных функций JS.

Так это:

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

будет транслироваться как это (попробуйте это в Babel REPL -> https://babeljs.io/repl/):

"use strict";

function read_file(file) {

  var delete_after =
    arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  
  //Code...

}

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

avatar
Kamil Kiełczewski
30 июня 2020 в 14:30
0

Да - доказательство:

function read_file(file, delete_after = false) {
  // Code
  console.log({file,delete_after});
}



// TEST
read_file("A");
read_file("B",true);
read_file("C",false);
avatar
Shivang Gupta
19 декабря 2019 в 08:39
2

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

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';
    ...
}
avatar
jave.web
17 октября 2019 в 20:22
3

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

В будущем вы сможете «распространять» один объект на другой (в настоящее время с 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
}
frank-dspeed
13 декабря 2019 в 13:29
0

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

frank-dspeed
13 декабря 2019 в 14:19
0

function test (options) {/ * Параметры определены, выдает ошибку, если вы используете const options = {} now * /}

frank-dspeed
14 декабря 2019 в 07:03
0

no not global, когда вы создаете функцию и передаете ее в качестве параметров имени аргумента, тогда внутри функции параметры определяются внутри function (opt) {} opt определяется, вы не можете использовать const opt ​​внутри этой функции, тогда это плохо, потому что вы это делаете переназначение переменной, если вы делаете это часто, и похоже, что ваш общий шаблон - это проблема

jave.web
16 декабря 2019 в 12:45
0

@ google-frank-dspeed а, ты имеешь в виду, что не можешь function(opt){ const opt = /*some merging*/; }? Это точно не сработает, потому что вы использовали бы const переменную до того, как она была объявлена ​​ - вам придется отрегулировать - function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }

jave.web
16 декабря 2019 в 13:00
0

@ google-frank-dspeed в любом случае больше новых людей, вероятно, зададутся вопросом об этом, поэтому я добавил код с инструкциями для редактирования :) так что спасибо, что указали на это для других :)

avatar
new QOpenGLWidget
16 июля 2019 в 16:26
-1

Ответ - да. Фактически, есть много языков, которые поддерживают параметры по умолчанию. 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 строку кода меньше, чем стандартный способ определения параметра сразу после запуска функции.

EDIT: И это очень важно! Это не будет работать в IE. См. документацию. Таким образом, с IE вы должны использовать метод «определить переменную в верхней части функции». Параметры по умолчанию не будут работать в IE.

avatar
Aman Pandey
13 июня 2019 в 09:26
0

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

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

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

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

avatar
Alireza
18 января 2019 в 07:29
4

Да, использование параметров по умолчанию полностью поддерживается в 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 один будет заменен только в том случае, если только переданное значение истинно, потому что способ || работает ...

avatar
Akrion
10 октября 2018 в 07:04
3

Если по какой-то причине вы не на 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 или не определено <63819729907

avatar
esewalson
27 сентября 2018 в 16:56
1

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

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

Синтаксис:

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
avatar
Muhammad Rizwan
24 сентября 2018 в 23:02
0
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 ему присваивается значение undefined . Этот подход не выглядит привлекательным программно, но имеет обратную совместимость .

avatar
Angel Politis
12 августа 2018 в 05:26
5

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


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

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}
avatar
Willem van der Veen
8 августа 2018 в 15:48
5

Если вы используете 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, если нет, он возвращает значение правой стороны. Когда функция вызывается без соответствующего аргумента, JS-движок устанавливает переменную параметра (bar в нашем примере) на undefined. undefined Затем преобразуется в false, и поэтому оператор OR возвращает значение 0.

avatar
BlackBeard
5 июля 2018 в 11:54
5

Используйте это, если вы хотите использовать последний синтаксис 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. Он позволяет инициализировать формальные параметры значениями по умолчанию, если значение не передано или не определено. ПРИМЕЧАНИЕ : Он не будет работать с 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, если при вызове этой функции не было передано значение параметра.

MagicLAMP
16 ноября 2018 в 02:31
0

ПРИМЕЧАНИЕ: как говорит @BlackBeard, функция (param = value) НЕ БУДЕТ работать с IE. Используйте совместимую версию.

avatar
dutta
1 июля 2018 в 08:50
4

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

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

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

avatar
Tính Ngô Quang
8 июня 2018 в 08:55
5
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!!!
avatar
Doug Coburn
15 октября 2017 в 22:36
12

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

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

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

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

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

instead
26 января 2019 в 17:36
1

Это «лучшее решение» совершенно нечитаемо. Я бы предпочел проверить тип переменной, например typeof deleteAfter === 'bool', и в противном случае выбросить исключение. Кроме того, в случае использования таких методов, как map / foreach и т. Д., Просто используйте их с осторожностью и оберните вызываемые функции анонимной функцией. ['1', '2', '3'].map((value) => {read_file(value);})

Doug Coburn
26 января 2019 в 18:18
0

Неплохо подмечено. Я пытался избежать использования библиотек в своем фрагменте кода, но эта идиома довольно запутана в чистом javascript. Лично я бы использовал метод lodash get для получения deleteAfter. Создание исключения, если typeof 'deleteAfter' !== 'bool' также может быть хорошей разумной мерой. Мне не нравится разрабатывать методы, требующие от вызывающего абонента «осторожности». За осторожность отвечает функция, а не вызывающая сторона. Конечное поведение должно соответствовать принципу наименьшего удивления.

instead
26 января 2019 в 23:52
0

Я согласен, этот метод нельзя писать так, чтобы его вызов мог нарушить его поведение. Но имейте в виду, что функция похожа на модель, а вызывающая сторона похожа на контроллер. Модель должна позаботиться об обработке данных. Функция (метод) должна ожидать, что данные могут быть переданы неправильно, и обработать их. Вот почему проверка типа параметра плюс выброс исключения - лучший способ. Хотя это более сложно. Но все же это может спасти Вас от того, чтобы чесать голову и постоянно спрашивать ... ПОЧЕМУ ЭТО НЕ РАБОТАЕТ ?! а потом ... ПОЧЕМУ ЭТО РАБОТАЕТ ?!

avatar
Sachin Kumar
15 октября 2017 в 20:40
5

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

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

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

avatar
Thalaivar
15 октября 2016 в 17:58
30

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

С 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
avatar
Steven Johnston
3 августа 2016 в 14:49
8

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

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

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

Чтобы обойти это, используйте

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

По состоянию на 8 августа 2016 г. проблема все еще сохраняется

avatar
Muhammad Awais
19 июля 2016 в 11:59
-3

Да, это будет работать в 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
Gert van den Berg
11 мая 2017 в 08:34
2

В настоящее время он не переносится ... IE ... developer.mozilla.org/en/docs/Web/JavaScript/Reference/… (И это повторяющийся ответ ...)

avatar
vivek
19 мая 2016 в 06:40
9

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

function myfunc(a,b=10)

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

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

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

DiMono
19 июля 2016 в 02:52
3

Назначение в определении функции также не работает в IE 11, который является самой последней версией IE для Windows 8.1.

gcampbell
18 сентября 2016 в 09:00
1

Если кому-то интересно, function myfunc(a,b=10) - это синтаксис ES6, в других ответах есть ссылки на таблицы совместимости.

avatar
Takács Zsolt
16 ноября 2015 в 11:29
15

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

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}
Dmitri Pavlutin
20 декабря 2015 в 09:33
4

Что произойдет, если delete_after будет 0 или null? В этих случаях это не сработает.

Rutrus
1 февраля 2017 в 10:13
0

@StephanBijzitter это было бы правдой только в некоторых случаях. Но если вы хотите, чтобы значения по умолчанию не устанавливались, это не сработает, потому что 0 или null! === false.

Stephan Bijzitter
1 февраля 2017 в 10:21
0

@Rutrus: Я ничего не понимаю, что вы только что сказали.

aashah7
28 апреля 2017 в 03:50
0

А как насчет delete_after = delete_after === undefined ? false : delete_after?

avatar
Martin Wantke
16 ноября 2015 в 07:34
11

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

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}
avatar
zillaofthegods
6 октября 2015 в 16:16
10

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

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

f(1) === 50

На основании ссылки - http://es6-features.org/#DefaultParameterValues

user
6 ноября 2015 в 00:48
11

Этот ответ бесполезен, потому что это дубликат

avatar
Felix Kling
29 мая 2015 в 15:25
66

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

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

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

Дополнительную информацию см. В статье MDN.

Zac
1 июня 2015 в 20:15
1

ECMAScript 6, я полагаю ... (я бы исправил сам, но я не могу вносить правки <6 символов)

Adriano Resende
8 июля 2015 в 13:05
1

Жду браузер любой получить ECMAScript 6

harryg
9 июля 2015 в 11:31
1

Что бы Вавилон это передал?

Felix Kling
9 июля 2015 в 13:22
2

@harryg: babeljs.io/repl/…

freemanoid
9 июля 2015 в 19:03
2

Вот таблица совместимости для ES6 kangax.github.io/compat-table/es6/#default_function_parameters К сожалению, этот синтаксис еще не поддерживается .

avatar
TJ L
21 мая 2009 в 20:18
152

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

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

function myFunc(x) {
  x = pick(x, 'my default');
} 
andersand
15 августа 2014 в 20:12
6

Обновление: если вы уже используете underscore.js , я считаю, что даже лучше использовать _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. Использование глобального пространства имен, как показано в этом ответе, многими считается плохой практикой. Вы также можете рассмотреть возможность использования собственной утилиты для этой общей задачи (например, util.default(arg, "defaul value")), если не хотите использовать подчеркивание, но я в большинстве случаев в конечном итоге использую подчеркивание рано или поздно, в любом случае нет смысла изобретать колесо.

JasonDavis
13 октября 2014 в 02:08
0

@anders и мне нравится идея чего-то вроде util.default(arg, "defaul value")) , не могли бы вы или @ tj111 опубликовать быструю демонстрацию?

user2039981
21 апреля 2015 в 16:59
2

Я действительно рекомендую этот, я использую его и называю его «пор», что означает «параметр или».

OsamaBinLogin
20 октября 2015 в 15:06
2

Не говорите typeof arg == 'undefined', вместо этого скажите arg === undefined

Alnitak
16 ноября 2015 в 11:34
3

@OsamaBinLogin то, что вы говорите, правильно для текущего JS - старый тест сохраняется, потому что в некоторых браузерах можно было перезаписать undefined другим значением, что привело к сбою теста.

Mr. Lance E Sloan
14 июня 2017 в 20:27
2

@Alnitak: Еще можно переопределить undefined. Итак, по-прежнему рекомендуется использовать typeof и 'undefined'.

Alnitak
15 июня 2017 в 08:40
0

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

avatar
Russ Cam
21 мая 2009 в 20:09
614
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, <2493446517> или <24189344 Если вам требуется передать значения 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" }); 
Tom Ritter
21 мая 2009 в 20:11
118

Я считаю, что этого недостаточно, потому что я могу передать ложь.

Russ Cam
21 мая 2009 в 20:16
52

Я считаю, что это подходит для большинства ситуаций

jinglesthula
31 октября 2012 в 20:34
51

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

xbonez
28 ноября 2012 в 05:56
1

Почему в этом случае delete_after не получает логический результат выражения delete_after || "my default value"?

Russ Cam
28 ноября 2012 в 19:36
0

@xbonez присваивает delete_after значение delete_after, если это не значение falsey , в противном случае присваивает строку my default here. Для получения дополнительных сведений ознакомьтесь с обзором языка Дугом Крокфордом и ознакомьтесь с разделом Операторы - javascript.crockford.com/survey.html

Muhammad Raihan Muhaimin
19 февраля 2014 в 21:04
0

Вот загвоздка: «Этот подход не работает, если вы хотите передать ложное значение, то есть false, null, undefined, 0 или" ". Если вам требуется передать ложные значения, вам нужно будет использовать метод в Tom Ответ Риттера ". Спасибо за разъяснение.

Paul
4 августа 2015 в 13:39
0

Это может не сработать, если вам нужны ложные значения, но мои функции часто принимают необязательный объект параметров. Это идеально подходит для этого варианта использования: opts = opts || {}.

beerwin
22 октября 2015 в 09:45
0

Это может быть лучше так: delete_after = typeof(delete_after) != 'undefined' ? delete_after : "my default here";

Mark Brackett
27 марта 2016 в 01:33
3

или вы можете просто по умолчанию использовать значение falsey - что в любом случае является хорошим значением по умолчанию (например, false для bools, пустая строка для строк, 0 для чисел и т. д.) - в этом случае на самом деле не имеет значения, что было прошел внутрь.

ArtOfWarfare
5 июня 2016 в 00:58
0

Может ли function быть ложным?

Mr. Lance E Sloan
14 июня 2017 в 20:25
0

@jinglesthula предполагает, что такой подход может создать кошмар обслуживания. Скажу сильнее: скорее всего, это будет кошмар. Расс Кэм писал, что этот подход не будет работать, если используются значения, которые можно преобразовать в Boolean false. Если вы используете этот подход, как вы можете быть уверены, что ваш код не будет вызван с ложным значением? Вы не можете. Следовательно, такой подход - не лучшая идея. Единственный текущий безопасный подход - использовать typeof и сравнивать результаты с 'undefined'.

jinglesthula
14 июня 2017 в 20:48
0

К счастью, теперь у нас есть ES6 (и Babel), так что это будет скорее спорный вопрос, поскольку язык изначально поддерживает это разумным образом. Для тех, кто еще не использует ES6, я думаю, что фраза «если вам нужны ложные значения» или «если вы хотите передать ложное значение» немного вводит в заблуждение, поскольку вам могут быть переданы ложные значения, которых вы не ожидали при написании кода. либо потому, что то, что вы пишете, будет использоваться другими людьми, либо вашим будущим «я» (что практически то же самое, что и «другие люди»), забывшим небольшую оговорку, встроенную в старый код.

Vojtech Ruzicka
9 января 2018 в 10:24
0

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

Sumesh TG
5 июля 2018 в 12:12
0

Это работает как с переменными, так и с объектами. Спасибо.

Sergey
24 октября 2018 в 10:23
0

Первый пример не универсален, потому что он не будет работать в случае с таким методом, как setValue(v), если вы передадите 0, где v по умолчанию должно быть 1. Он будет работать только со строками и объектами.