ES6のパラメーターとしてnull
を渡すと、デフォルトのパラメーターが提供されたときに使用されないという既知の理由はありますか?
function sayHello(name = "World") {
console.log("Hello, " + name + "!");
}
sayHello("Jim"); // Hello, Jim!
sayHello(undefined); // Hello, World!
sayHello(null); // Hello, null!
undefined
がnull
と完全に異なる理由についてのコメントを読んだことがあり、それがデフォルトパラメータの現在の動作を説明している理由です。
関数を持っているときは、未定義のを明示的に渡すとデフォルト値の置換がトリガーされないと主張できます。
_const f = (x = 'default') => console.log(x);
_
次のように実行すると_"default"
_が出力されます。
_f();
_
しかし、明示的に次のように実行したときに_"undefined"
_を出力したいと思います。
_f(undefined);
_
さもなければ、なぜ最初にf(undefined)
を使用するのでしょうか?ここでの私の意図は明らかに、それを除外するのではなく、何らかの議論を提供することです。
ここで、この機能を検討してください。
_const g = (...a) => console.log(JSON.stringify(a));
_
私がそれを使用するとき:
_g();
_
取得:_[]
_
ただし、次のように使用する場合:
_g(undefined);
_
取得:_[null]
_
次のことを明確に示しています。
undefined
を渡すことは、引数をまったく渡さないことと同じではありませんnull
がundefined
の代わりにデフォルト値になりますデフォルトパラメータの現在の動作に関する背景は、TC39による2012年7月24日のミーティングノートで見ることができます。
ちなみに、最初に明示的にundefined
を渡すとdid notが最初のドラフトのデフォルト値をトリガーし、それを行うべきかどうかについての議論があったことを示しています。ご覧のとおり、現在の動作はTC39のメンバーにとってそれほど明白ではありませんでした。
そうは言っても、何がデフォルト値の置換をトリガーすべきか、何をトリガーすべきではないかの決定は、その日の終わりには完全に任意です。別々にundefined
とnull
を用意しても、考えてみると非常に奇妙に思えます。一部の言語はundefined
のみ(Perlのundef
など)、一部の言語はnull
のみ(Javaなど)、一部の言語ではfalse
と同等または空のリストまたは配列を使用しますそれ(空のリストまたは_#f
_(false)を持つことができるSchemeのように、空のリストとfalse値の両方から区別されるnull
に相当するものはありません) null
、false
、またはundefined
と同等のものもあります(true
およびfalse
の代わりに整数を使用するCなど、実際には通常のNULLポインターアドレス0を指すポインター-nullポインターをテストするコードによってマップされた場合でも、そのアドレスにアクセスできなくなります。
これで、null
をデフォルト値に置き換える必要があることを理解できました。残念ながら、これはデフォルトの動作ではありませんが、次のような簡単な関数を作成できます。
_const N = f => (...a) => f(...a.map(v => (v === null ? undefined : v)));
_
これで、null
値の代わりにデフォルトを使用するたびに、このように使用できます。例えば。上記の例のいずれかからこの関数を使用している場合:
_const f = (x = 'default') => console.log(x);
_
f()
およびf(undefined)
に対しては_"default"
_を出力しますが、f(null)
に対しては出力しません。ただし、上記で定義したN
関数を使用して、次のようにf
関数を定義すると、
_const f = N((x = 'default') => console.log(x));
_
現在f()
とf(undefined)
が、f(null)
も_"default"
_を出力します。
多少異なる動作が必要な場合、例えば空の文字列をデフォルト値に置き換える-存在しないのではなく空の文字列に設定されることがある環境変数に便利で、次を使用できます。
_const N = f => (...a) => f(...a.map(v => (v === '' ? undefined : v)));
_
すべての偽の値を置換する場合は、次のように使用できます。
_const N = f => (...a) => f(...a.map(v => (v || undefined)));
_
空のオブジェクトを置き換える場合は、次を使用できます。
_const N = f => (...a) => f(...a.map(v => (Object.keys(v).length ? v : undefined)));
_
等々...
重要なのは、それがあなたのコードであり、関数のAPIとは何か、そしてデフォルト値がどのように機能するかを知っているということです。幸いなことに、JavaScriptは強力な機能を備えているため、必要なものを簡単に実現できます(いわば、それがデフォルト値のデフォルトの動作ではない場合でも)。
これが、仕様でデフォルトパラメータが定義されている方法です。 [〜#〜] mdn [〜#〜] :(エンファシス鉱山)を参照
デフォルト関数パラメーターを使用すると、値なしまたは未定義が渡された場合に、デフォルト値で仮パラメーターを初期化できます。
null
はno valueでもundefined
でもないため、デフォルトの初期化をトリガーしません。
null
は、使用されるデフォルト値をトリガーしない値です。引数がundefined
の場合、デフォルト値が使用されます。