Питання Встановіть значення параметра за замовчуванням для функції JavaScript


Я хотів би, щоб функція JavaScript мала необов'язкові аргументи, якими я встановив значення за замовчуванням, який використовується, якщо значення не визначено. У Ruby ви можете зробити це так:

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

Чи працює ця функція в JavaScript?

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

2022
2018-05-21 20:07


походження




Відповіді:


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

Є багато способів, але це мій найкращий спосіб - він дозволяє передавати усе, що завгодно, у тому числі помилковим або нульовим. (typeof null == "object")

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

2937
2018-05-21 20:10



Ви також можете інкапсулювати його як такий: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; } і тоді ви можете назвати це як a = defaultFor(a, 42); - Camilo Martin
@SiPlus, і ви отримали додаткові помилки помилок під час користування undefined об'єкти: p Навіть, коли він може працювати з деякими браузерами і може бути швидшим null як і раніше є об'єктом і undefined це посилання на примітивний тип, який намагається сказати, що тут немає нічого, навіть null. Дивіться тут, обидва випадки в двох словах: JavaScript / Reference / Global_Objects / undefined. - Sampo Sarrala
якщо ви перевіряєте власність об'єкта, то typeof є зайвим. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; } Це не призведе до помилок довідки та коротко. - Dziamid
Я знаю, що це дійсно незначне, але мені не подобається, як ви призначаєте a = a і b = b коли ці параметри не визначені. Також цей трійковий оператор з трохи складним станом може бути важко читати для майбутніх супроводжуючих. Я віддаю перевагу наступному синтаксису: if (typeof a == 'undefined') a = 42 - немає зайвої доручення плюс трохи легше для читання. - Daddy32
Є якісь причини для використання typeof? Здавалося б, простіше просто зробити a === undefined. Плюс такий спосіб ви отримаєте помилку посилання, якщо ви неправильно напишете undefined проти його введення в рядок. - Abe Voelker


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

Це призначено для delete_after вартість delete_after якщо це не а брехливий в іншому випадку він призначає рядок "my default here". Для більш докладної інформації, перевірте Опитування Даґ Крокфорда про мову та ознайомтесь із розділом "Оператори".

Цей підхід не працює, якщо ви хочете передати в a брехливий значення, тобто false, null, undefined, 0 або "". Якщо вам потрібно брехливий Значення, що передаються у вас, повинні використовувати метод в Відповідь Тома Риттера.

При роботі з рядом параметрів до функції часто корисно дозволити споживачеві передавати аргументи параметра в об'єкті, а потім злиття ці значення з об'єктом, який містить значення за замовчуванням для функції

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

559
2018-05-21 20:09



Я вважаю це недостатнім, тому що я, можливо, захочу передати помилкові. - Tom Ritter
Я вважаю це адекватним для більшості ситуацій - Russ Cam
Це також не працює для 0. :( - Alex Kahn
Вона не працює для будь-яких хибних значень - Russ Cam
Оскільки це не спрацьовує за хибні цінності, це може створити кошмар кошмару. Трохи коду, який завжди пройшов істинні цінності до того, як він несподівано стане невдалою, тому що помилковий пропущений, напевно, слід уникати там, де доступний більш надійний підхід. - jinglesthula


Я вважаю, що щось просте, подібне до цього, набагато лаконічніше і особисто читабельно.

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

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

137
2018-05-21 20:18



Оновлення: якщо ви використовуєте underscore.js Я вже вважаю, що це навіть краще використовувати _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. Використання глобального простору імен, як показано в цій відповіді, багатьма вважається поганою практикою. Ви також можете розглянути можливість переміщення власної утиліти для цього спільного завдання (наприклад,. util.default(arg, "defaul value")), якщо не хочете використовувати підкреслення, але я в основному в кінцевому підсумку використовуючи підкреслення рано чи пізно, в будь-якому випадку немає сенсу винаходити колесо. - andersand
@andersand мені подобається ідея щось на зразок util.default(arg, "defaul value"))  Ви б або @ tj111 зауважили, що публікуєте швидку демонстрацію? - JasonDavis
Я насправді рекомендую цей, я використовую його і називаю його "por", що означає "параметр або" - super
Не повідомляйте typeof arg == 'undefined', а не аргумент === undefined - OsamaBinLogin
@OsamaBinLogin те, що ви кажете, є правильним для поточної JS - старший тест зберігається, оскільки в деяких браузерах це було можливо для перезапису undefined з якоюсь іншою цінністю, що спричиняє невдачу тесту. - Alnitak


У ECMAScript 6 ви зможете точно написати саме те, що маєте:

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

Це буде встановлено delete_after до false якщо його немає або undefined. Ви можете використовувати такі функції ES6, як цей сьогодні, з трансплікаторами, такими як Вавилон.

Див. Статтю MDN для отримання додаткової інформації.


54
2018-05-29 15:25



ECMAScript 6 Я думаю ... (я б виправив сам, але не можу редагувати <6 символів) - Zac
Очікування браузера для отримання ECMAScript 6 - Adriano Resende
Що буде робити Вавілону? - harryg
@harryg: babeljs.io/repl/... - Felix Kling
Ось таблиця сумісності для ES6 kangax.github.io/compat-table/es6/#default_function_parameters На жаль, це синтаксис ще не підтримується. - freemanoid


Значення параметрів за замовчуванням

З 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. Щоб виправити цю готча, деякі люди замість цього напишуть чек більш verbosely, як це:

function foo(x,y) {
 x = (x !== undefined) ? x : 11;
 y = (y !== undefined) ? y : 31;
 console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17

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

function foo(x = 11, y = 31) {
 console.log( x + y );
}

foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`

x = 11 в декларації функції більше схожий x !== undefined ? x : 11 ніж набагато більш загальний ідіом x || 11

Вирази Значення за умовчанням

Function значення за замовчуванням можуть бути більше, ніж прості значення, такі як 31; вони можуть бути будь-якими правильними виразами, навіть а function call:

function bar(val) {
 console.log( "bar called!" );
 return y + val;
}
function foo(x = y + 3, z = bar( x )) {
 console.log( x, z );
}
var y = 5;
foo(); // "bar called"
 // 8 13
foo( 10 ); // "bar called"
 // 10 15
y = 6;
foo( undefined, 10 ); // 9 10

Як видно, вирази за умовчанням лениво оцінюються, тобто вони запускаються тільки тоді, коли вони потрібні, тобто коли аргумент параметра опущений або не визначено.

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

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

18
2017-10-15 17:58





це рішення для мене працює в js:

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

8
2017-11-16 11:29



Що буде, якщо delete_after є 0 або null? Це не спрацює правильно для цих випадків. - Dmitri Pavlutin
@StephanBijzitter це було б правдою в деяких випадках. Але якщо вам потрібні лише значення за замовчуванням, щоб скинути значення, це не спрацювало, тому що 0 або нуль! === false. - Rutrus
@Rutrus: Я не розумію нічого, що ти тільки що сказав. - Stephan Bijzitter
А як на рахунок delete_after = delete_after === undefined ? false : delete_after? - aashah7


Просто використовуйте явне порівняння з undefined.

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

6
2017-11-16 07:34





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

function myfunc(a,b=10)

Але будьте обережні, що він не працює послідовно в усіх веб-переглядачах. Для мене це працювало на chrome на моєму робочому столі, але не працювало на chrome на Android. Більш безпечний варіант, як багато хто вже згадував вище, -

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

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


5
2018-05-19 06:40



Завдання в рамках визначення функції також не працює в IE 11, що є найновішою версією IE для Windows 8.1. - DiMono
У випадку, якщо хтось цікавить, function myfunc(a,b=10) це синтаксис ES6, в інших відповідях є посилання на таблиці сумісності. - gcampbell


Як оновлення ... з ECMAScript 6 ви можете ЗАВЖДИ встановіть значення за замовчуванням у декларації функціональних параметрів, наприклад:

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

f(1) === 50

Як називається - http://es6-features.org/#DefaultParameterValues


4
2017-10-06 16:16



Ця відповідь не є корисною, оскільки вона є дублікатом - user


Усім, хто зацікавлений в тому, щоб кодувати роботу в 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 року це ще одна проблема


4
2017-08-03 14:49