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


2366

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

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

Чи працює це в JavaScript?

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

Відповіді:


3296

У 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';
  ...
}

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

6
@SiPlus, і ви отримали додаткові помилки посилань безкоштовно під час спроби використання undefinedоб'єктів: p Навіть якщо він може працювати з деякими браузерами і може бути швидшим, nullвін все ще є об'єктом і undefinedпосилається на примітивний тип, який намагається сказати, що існує тут нічого, навіть null. Дивіться, обидва випадки в двох словах: JavaScript / Довідка / Global_Objects / undefined .
Сампо Саррала - codidact.org

9
якщо ви перевіряєте властивість об'єкта, то typeofце зайве. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }Це не кине посилання на помилки і є стислим.
Дзямід

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

12
Чи є причина використовувати typeof? Здавалося б, просто зробити це a === undefined. Плюс до цього ви отримаєте помилку посилання, якщо помилково написали undefinedта покладете її в рядок.
Абе Волкер

599
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або "". Якщо вам потрібно передати значення фальси, вам потрібно буде використовувати метод у відповіді Тома Ріттера .

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

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

115
Я вважаю це недостатньою, тому що, можливо, я хочу передати помилкове.
Том Ріттер

52
Я вважаю це адекватним для більшості ситуацій
Russ Cam

50
Оскільки це не працює для фальсифікованих значень, це може створити кошмар технічного обслуговування. Трохи коду, якому завжди передавались триєдні значення раніше, і раптом не вдається, тому що фальсифікат, який передається, слід, мабуть, уникати там, де є більш надійний підхід.
jinglesthula

1
Як же, в цьому випадку, delete_afterне виходить бульний результат виразу delete_after || "my default value"?
xbonez

3
або, ви можете просто за замовчуванням встановити значення фальси - що взагалі є хорошим за замовчуванням у будь-якому випадку (наприклад, false для bools, порожня рядок для рядків, 0 для чисел і т. д.) - у цьому випадку це насправді не має значення, що було пройшов в.
Марк Brackett

150

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

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

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

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

2
Я на насправді рекомендую цю, я використовую його і називаю його «Пор» , який виступає за «або параметр»
супер

2
Не кажіть typeof arg == 'undefined', а скажіть arg === undefined
OsamaBinLogin

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

2
@Alnitak: Перемогу все ще можливо undefined. Отже, це все-таки хороша ідея для використання typeofта 'undefined'.
LS

63

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

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

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

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


1
ECMAScript 6 Я гадаю, що ... (я б сам виправив, але я не можу вносити зміни <6 символів)
Зак

1
Чекаючи, коли браузер отримає ECMAScript 6
Adriano Resende

1
До чого б Вавілон перетворив це?
harryg


2
Ось таблиця сумісності для ES6 kangax.github.io/compat-table/es6/#default_function_parameters На жаль, цей синтаксис ще не підтримується .
freemanoid

27

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

За допомогою 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

13

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

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

4
Що відбувається, якщо delete_afterє 0чи null? У цих випадках це не вийде правильно.
Дмитро Павлутін

@StephanBijzitter це було б правдою лише в деяких випадках. Але якщо ви хочете лише, щоб значення за замовчуванням не встановлювали значення, це не спрацювало, тому що 0 або null! === false.
Рутрус

@Rutrus: Я нічого не розумію, що ви сказали.
Стефан Біцзіттер

Про що delete_after = delete_after === undefined ? false : delete_after?
aashah7

10

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

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

10

Я настійно рекомендую бути надзвичайно обережними при використанні значень параметрів за замовчуванням у JavaScript. Це часто створює помилки при використанні в поєднанні з функцій вищого порядку , таких як forEach, mapі reduce. Наприклад, розглянемо цей рядок коду:

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

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

Я пропоную вам відокремити необхідні параметри від аргументів необов’язкових / типових значень. Якщо ваша функція приймає 1,2 або 3 необхідних параметра, для яких значення за замовчуванням не має сенсу, зробіть їх позиційними параметрами функції, будь-які необов'язкові параметри повинні слідувати як названі атрибути одного об’єкта. Якщо ваша функція займає 4 або більше, можливо, має сенс подавати всі аргументи за допомогою атрибутів одного об'єктного параметра.

У вашому випадку я хотів би запропонувати вам написати функцію DeleteFile , як це: ( відредагованого на instead «S коментарі ) ...

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

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


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

Це хороший момент. Я намагався уникати використання бібліотек у своєму фрагменті коду, але ця ідіома досить безладна в чистому JavaScript. Особисто я використовую getметод lodash, щоб отримати deleteAfter. Закидання винятку, якщо typeof 'deleteAfter' !== 'bool'також може бути хорошим розумним заходом. Мені не подобається розробляти методи, які вимагають, щоб абонент "використовував обережність". Обережність - це відповідальність функції, а не абонента. Кінцева поведінка повинна слідувати принципу найменшого здивування.
Doug Coburn

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

9

Як оновлення ... за допомогою ECMAScript 6 ви можете НАЗАДНО встановити значення за замовчуванням у деклараціях функціональних параметрів так:

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

f(1) === 50

На що посилається - http://es6-features.org/#DefaultParameterValues


11
Ця відповідь не є корисною, оскільки це дублікат
користувач

8

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

function myfunc(a,b=10)

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

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

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


3
Призначення в межах визначення функції також не працює в IE 11, що є найбільш актуальною версією IE для Windows 8.1.
DiMono

1
Якщо хтось цікавить, чи function myfunc(a,b=10)це синтаксис ES6, в інших відповідях є посилання на таблиці сумісності.
gcampbell

7

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

Станом на 08 серпня 2016 року це все ще залишається проблемою


4

Відповідно до синтаксису

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

Ви можете визначити значення за замовчуванням формальних параметрів. а також перевірити невизначене значення за допомогою функції typeof .


4
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

Використовуйте це, якщо ви хочете використовувати останній 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якщо при виклику цієї функції не було передано значення параметра.


ПРИМІТКА: як говорить @BlackBeard, функція (param = значення) WONT працює з IE. Використовуйте сумісну версію.
MagicLAMP

4

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


ES5: Більшість з наведених відповідей не досить добре для мене , тому що є випадки , коли я , можливо , доведеться передати значення falsey , такі як 0, nullі undefinedдо функції. Щоб визначити, чи не визначено параметр, оскільки це значення, яке я передав замість невизначеного, через те, що не було визначено взагалі, я роблю це:

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}

3

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

Тут foo () - це функція, яка має параметр з назвою argValue. Якщо ми нічого не передаємо тут у виклику функції, то викине функція castIfNoValue () і повернутий результат буде призначений єдиному аргументу argValue. Ось як виклик функції може використовуватися як параметр за замовчуванням. Що робить код більш спрощеним і читабельним.

Цей приклад взятий звідси


3

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


3

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


2

Якщо з якихось - то причин ви НЕ на 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


1

Звуки майбутнього

Надалі ви зможете "поширити" один об'єкт на інший (зараз станом на 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 DOE - 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'});

EDIT: Через коментарі щодо 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
}

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

тест функцій (параметри) {/ * Опції визначені, це призведе до помилки, якщо ви будете використовувати параметри const = {} зараз * /}
відвертий dspeed

ні, не глобально, коли ви створюєте функцію, і ви передаєте як параметри імені аргументу, тоді всередині параметра функції визначено всередині функції (opt) {} визначено opt, ви не можете використовувати const opt ​​всередині цієї функції, то це погано, оскільки ви робите змінна переназначення, якщо ви робите це часто, і це виглядає як ваша загальна модель, це питання
відвертий день

@ google-frank-dspeed ах, ти маєш на увазі, що ти не можеш цього робити function(opt){ const opt = /*some merging*/; }? Це точно не спрацює, тому що ви будете використовувати constзмінну до її оголошення - вам доведеться коригувати -function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} }
jave.web

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

1

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

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

Так, це називається параметром за замовчуванням

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

Синтаксис:

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

0

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

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

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

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


-1

Відповідь - так. Насправді існує багато мов, які підтримують параметри за замовчуванням. Пітон є одним з них:

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.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.