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

2009-05-22 javascript function parameters arguments default-parameters

JavaScript関数にデフォルトを設定するオプションの引数を設定します。これは、値が定義されていない場合に使用されます(値が渡された場合は無視されます)。 Rubyでは、次のように実行できます。

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

これはJavaScriptで機能しますか?

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

Answers

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

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

このアプローチは、 false値、つまりfalsenullundefined0または""を渡す場合には機能しません。 誤った値を渡す必要がある場合は、 Tom Ritterの回答のメソッドを使用する必要があります

関数への多数のパラメーターを扱う場合、コンシューマーがオブジェクトのパラメーター引数を渡して、これらの値を関数のデフォルト値を含むオブジェクトとマージできるようにすることがしばしば役立ちます。

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

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

私はこのような単純なものがはるかに簡潔で個人的に読みやすいと思います。

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

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

ECMAScript 6では、実際にあなたが持っているものを正確に書くことができます:

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

これが存在しないかundefinedの場合、 delete_afterfalse設定されdelete_after 。今日、このようなES6の機能をBabelなどのトランスパイラーで使用できます。

詳細については、MDNの記事を参照してください

更新として... ECMAScript 6を使用すると、次のように関数パラメーター宣言にデフォルト値を最終的に設定できます。

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

f(1) === 50

参照先-http://es6-features.org/#DefaultParameterValues

undefinedとの明示的な比較を使用するだけです。

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

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

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

長い間C ++開発者(ルーキーからWeb開発:))でしたが、この状況に初めて遭遇したとき、質問で言及されているように、関数定義で次のようにパラメーターの割り当てを行いました。

function myfunc(a,b=10)

ただし、ブラウザ間で一貫して機能しないことに注意してください。私にとっては、デスクトップのクロムでは機能しましたが、Androidのクロムでは機能しませんでした。 多くの人が上で述べたように、より安全なオプションは-

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

この答えの意図は、他の人がすでに述べた同じ解決策を繰り返すことではなく、関数定義でのパラメーター割り当てが一部のブラウザーで機能する可能性があることを通知することですが、それに依存しないでください。

はい、これは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

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日現在、これはまだ問題です

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

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に直接渡されるのではなくx || 11 results in 11になります。この問題を修正するために、一部の人々は代わりに次のように冗長にチェックを記述します。

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 = 11x = 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

構文に従って

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

仮パラメータのデフォルト値を定義できます。 また、 typeof関数を使用して未定義の値を確認します。

JavaScriptでデフォルトのパラメータ値を使用する場合は、細心の注意を払うことを強くお勧めします。 forEachmapreduceなどの高次関数と組み合わせて使用​​すると、バグが発生することがよくあります。たとえば、次のコード行を考えてみます。

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

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

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

あなたの場合は、次のようにdeleteFile関数を書くことをお勧めします:( instead コメント ごと 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);

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

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

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

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

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

最新の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と呼ばれ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場合、パラメーター変数がundefinedであるという事実に依存しているため、両方の関数はまったく同じ動作をします。

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を返します。

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


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

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}
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に割り当てられます。このアプローチは、プログラム的には魅力的に見えませんが、 下位互換性があります。

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

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

構文:

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

何らかの理由であなたは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>

現在の値がNaNnull 、または未定義の場合にデフォルトを設定します

はい、デフォルトパラメータの使用は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に渡された場合、値が偽である場合でも、それらに大きな違いがあります。値は、 null""などの新しい値に置き換えられますが、 ES5のみが置き換えられます渡された値が真実である、それは方法が||ワーキング...

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

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

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

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

答えはイエスです。実際、デフォルトのパラメータをサポートする言語はたくさんあります。 Pythonはその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行少ないコードで済みます。

編集:そしてこれは非常に重要です!これはIE では機能しませんドキュメントを参照してください。したがって、IEでは「関数の上部に変数を定義する」メソッドを使用する必要があります。デフォルトのパラメータはIEでは機能しません。

未来の音

将来的には、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がサポートしているのは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
}

私のスキルも紹介するだけですが(笑)、上記の関数は次のように名前付き引数がなくても記述できます。

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

はい-証明:

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

Related