web-dev-qa-db-ja.com

JavaScript関数のデフォルトパラメータ値を設定します

JavaScript関数にデフォルトを設定するオプションの引数が欲しいのですが、それは値が定義されていない場合に使われます。 Rubyでは、このようにすることができます。

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

これはJavaScriptで動作しますか?

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

ES6/ES2015から、デフォルトパラメータは言語仕様になりました。

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

ただ動作します。

参照: デフォルトパラメータ - MDN

値なし または 未定義 が渡された場合、デフォルト関数パラメータを使用すると、仮パラメータをデフォルト値で初期化できます。

デフォルトのnamedパラメータをデストラクタリングでシミュレートすることもできます

// 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';
  ...
}
3094
Tom Ritter
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

これは、 falsey の値でない場合はdelete_afterの値をdelete_afterに割り当て、それ以外の場合は文字列"my default here"を割り当てます。詳細については、 Doug Crockfordによる言語調査と、Operators のセクションをご覧ください。

falsey の値、つまりfalsenullundefined0、または""を渡したい場合、このアプローチは機能しません。 falsey valuesを渡す必要がある場合は、 Tom Ritter's answer のメソッドを使用する必要があります。

関数への多数のパラメータを扱うとき、コンシューマがパラメータ引数をオブジェクトに渡し、次に merge これらの値を関数のデフォルト値を含むオブジェクトに渡すことができるようにすると便利です。

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

私はこのような単純なことが、もっと簡潔で読みやすい個人的なものであることに気付きます。

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

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

ECMAScript 6では、実際に自分の持っているものを正確に書くことができます。

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

これが存在しない場合はdelete_afterfalseに設定し、またはundefinedを設定します。 Babel のようなtranspilerで今日このようなES6の機能を使うことができます。

詳しくはMDNの記事を見てください 。 

59
Felix Kling

デフォルトのパラメータ値

ES6では、JavaScriptで最も一般的なイディオムの1つが、関数パラメータのデフォルト値の設定に関連している可能性があります。私たちが何年にもわたりこれを行ってきた方法は、かなりおなじみのはずです。

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

その解決策は私にとってjsでうまくいく:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}
10
Takács Zsolt

Undefinedとの明示的な比較を使うだけです。

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

長い間C++開発者(ルーキーからウェブ開発へ):私がこの状況に最初に出会ったとき、次のように質問で言及されているように、私は関数定義でパラメータ割り当てをしました。 

function myfunc(a,b=10)

しかし、それがブラウザ間で一貫して動作しないことに注意してください。私の場合、私のデスクトップではchromeを使用していましたが、Androidではchromeを使用していませんでした。

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

この答えの意図は、他の人がすでに述べたのと同じ解決策を繰り返すことではなく、関数定義におけるパラメータ割り当てがいくつかのブラウザでうまくいくかもしれないことを知らせることですが、それに頼らないでください。

7
vivek

更新として... ECMAScript 6では、 _ finally _ のように関数パラメータ宣言でデフォルト値を設定することができます。

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

f(1) === 50

- http://es6-features.org/#DefaultParameterValues によって参照されるように - /

7
zillaofthegods

JavaScriptでデフォルトのパラメータ値を使用する場合は、細心の注意を払ってください。 forEachname__、mapname__、およびreducename__のような高階関数と組み合わせて使用​​すると、しばしばバグが発生します。たとえば、次のコード行を見てください。

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

parseIntにはオプションの2番目のパラメーターfunction parseInt(s, [ radix =10])がありますが、マップ呼び出しparseIntname__には3つの引数(elementindex、およびarray)があります。

私はあなたがあなたのオプション/デフォルト値の引数からあなたの必須のパラメータを分けることを勧めます。関数がデフォルト値が意味をなさない1、2、または3つの必須パラメータを取る場合、それらを関数への位置パラメータにします。あなたの関数が4以上を取る場合、おそらくそれは単一のオブジェクトパラメータの属性を介してすべての引数を供給することがより理にかなっています。

あなたの場合、私はあなたが次のようにあなたのdeleteFile関数を書くことを勧めます:(編集されたinsteadname __のコメント)...

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

上記のスニペットを実行すると、未使用のパラメータに対するデフォルトの引数値の背後に潜んでいる危険性がわかります。

7
Doug Coburn

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
}

2016年8月8日現在、これはまだ問題です

6
Steven Johnston

ES6: ES6では、ほとんどの回答で既に述べたように、パラメータを値と共に初期化するだけで済みます。


ES5: 0nullundefinedなどの誤った値を関数に渡さなければならない場合があるため、与えられた答えのほとんどは私にとって十分ではありません。パラメータが未定義であるかどうかを判断するには、定義されていないために未定義ではなく渡された値であるため、次のようにします。

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}
3
Angel Politis
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!!!
3
TinhNQ

構文に従って 

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

仮パラメータのデフォルト値を定義することができ、また typeof functionを使用して未定義の値をチェックすることができます。

3
sachin kumar

最新の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 と呼ばれます。値が指定されていないか未定義である場合、仮パラメータをデフォルト値で初期化できます。 _ note _ :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になります。

3
BlackBeard

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

ここでfoo()はargValueという名前のパラメータを持つ関数です。ここで関数呼び出しに何も渡さないと、関数throwIfNoValue()が呼び出され、返された結果は唯一の引数argValueに割り当てられます。これが、関数呼び出しをデフォルトのパラメータとして使用する方法です。これにより、コードがより単純化されて読みやすくなります。

この例はここから取られました

2
dutta

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に変換できる場合は常に最初の値を返します。対応する引数なしで関数が呼び出されると、パラメータ変数(この例ではbar)はJSエンジンによってundefinedに設定されます。 undefined次にfalseに変換され、したがってOR演算子は値0を返します。

2

何らかの理由であなたがES6ではでなく、areusing 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>

現在の値がNaNnull、または未定義)の場合、デフォルトが設定されます。

1
Akrion

はい、デフォルトパラメータの使用は 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
}

つまり、値がある場合は値を使用し、それ以外の場合は||操作の後に2番目の値を使用します。これは同じことを行います...

注: また、 ES6 に値を渡すと、値が誤っていても、大きな違いがあります。nullname__や""など、新しい値に置き換えられます。 .. but ES5 渡された値だけが真の場合にのみ置き換えられます。これは||が機能するための方法です...

1
Alireza
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
Muhammad Rizwan

デフォルトのパラメータを設定するための別のアプローチは、引数を直接ではなく、引数のオブジェクトマップを使用することです。例えば、

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

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

これにより、引数を簡単に拡張でき、引数の長さの不一致を心配する必要がありません。

0
Aman Pandey

ええ、これはデフォルトのパラメータと呼ばれています

デフォルト関数パラメータを使用すると、値が指定されていないか未定義のパラメータが渡された場合、仮パラメータをデフォルト値で初期化できます。

構文:

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をスローすることはできません(現在、SpiderMonkeyではTypeErrorです。バグ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
esewalson