JavaScriptでオプションの関数パラメーターを実行するより良い方法はありますか? [複製]
-
02-07-2019 - |
質問
この質問にはすでに回答があります:
JavaScriptのオプションパラメータは常に次のように処理しました。
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
より良い方法はありますか?
そのような ||
の使用が失敗する場合はありますか?
解決
optionalArgが渡された場合、ロジックは失敗しますが、falseと評価されます-代替としてこれを試してください
if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }
または代替イディオム:
optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;
意図を最もよく伝えるイディオムを使用してください!
他のヒント
ECMAScript 2015(別名" ES6")では、関数宣言でデフォルトの引数値を宣言できます:
function myFunc(requiredArg, optionalArg = 'defaultValue') {
// do stuff
}
それらの詳細については、 MDNに関するこの記事をご覧ください。
これは現在 Firefoxでのみサポートされていますが、標準が完成しました。サポートが急速に向上することを期待してください。
編集(2019-06-12):
現在、最新のブラウザではデフォルトのパラメータが広くサポートされています。 Internet Explorerのすべてのバージョンは、この機能をサポートしていません。ただし、Chrome、Firefox、およびEdgeは現在サポートしています。
これが最も簡単で読みやすい方法だと思います:
if (typeof myVariable === 'undefined') { myVariable = 'default'; }
//use myVariable here
ポール・ディクソンの答えは(私の謙虚な意見では)これより読みにくいですが、好みに帰着します。
insinの答えははるかに高度ですが、大きな機能にはさらに便利です!
EDIT 11/17/2013 9:33 pm: Node.jsのパッケージを作成しました。これにより、「オーバーロード」しやすくなりました。 parametric と呼ばれる関数(メソッド)。
リテラルの NULL
をチャックインする必要がある場合、いくつかの問題が発生する可能性があります。それとは別に、いいえ、あなたはおそらく正しい軌道に乗っていると思います。
他の人々が選択するもう1つの方法は、引数リストを反復処理する変数の連想配列を取得することです。少し見栄えが良いように見えますが、プロセス(メモリ)を少し(非常に)集中的に使用していると思います。
function myFunction (argArray) {
var defaults = {
'arg1' : "value 1",
'arg2' : "value 2",
'arg3' : "value 3",
'arg4' : "value 4"
}
for(var i in defaults)
if(typeof argArray[i] == "undefined")
argArray[i] = defaults[i];
// ...
}
理想的には、オブジェクトを渡し、デフォルトのオブジェクトとマージするようにリファクタリングします。どの引数が渡されるかは関係ありません(この回答の2番目のセクションを参照してください)。
ただし、高速で信頼性が高く、使いやすく、かさばらないものが必要な場合は、これを試してください:
任意の数のデフォルト引数のクリーンクイックフィックス
- エレガントなスケーリング:新しいデフォルトごとに最小限の追加コード
- どこにでも貼り付けることができます。必要な引数と変数の数を変更するだけです
- この方法では、
undefined
をデフォルト値の引数に渡す場合、変数はundefined
として設定されます。このページの他のほとんどのオプションは、undefined
をデフォルト値に置き換えます。
3つのオプション引数(2つの必須引数)のデフォルトを提供する例です
function myFunc( requiredA, requiredB, optionalA, optionalB, optionalC ) {
switch (arguments.length - 2) { // 2 is the number of required arguments
case 0: optionalA = 'Some default';
case 1: optionalB = 'Another default';
case 2: optionalC = 'Some other default';
// no breaks between cases: each case implies the next cases are also needed
}
}
シンプルなデモ 。これは roenvingの回答に似ていますが、任意の数のデフォルト引数に対して簡単に拡張でき、更新が簡単で、 Function.arguments ではなく
。 arguments
を使用コード>
柔軟性を高めるためのオブジェクトの受け渡しとマージ
上記のコードは、デフォルトの引数を実行する多くの方法と同様に、引数を順番通りに渡すことはできません。たとえば、 optionalC
を渡すが、 optionalB
デフォルト。
そのための適切なオプションは、オブジェクトを渡し、デフォルトのオブジェクトとマージすることです。これは保守性にも優れています(コードを読みやすい状態に保つように注意してください。そうすれば、今後の協力者は、渡すオブジェクトの可能な内容について推測することはありません)。
jQueryを使用した例。 jQueryを使用しない場合は、代わりにUnderscoreの _。defaults(object、defaults)
またはこれらのオプションを参照:
function myFunc( args ) {
var defaults = {
optionalA: 'Some default',
optionalB: 'Another default',
optionalC: 'Some other default'
};
args = $.extend({}, defaults, args);
}
そのためにいくつかの異なるスキームを使用できます。 arguments.lengthについては常にテストしてきました:
function myFunc(requiredArg, optionalArg){
optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg;
...
-そうすると、失敗することはないかもしれませんが、あなたの方法が失敗する可能性があるかどうかはわかりません、今は実際に失敗するシナリオを考えることができません...
そして、ポールは失敗したシナリオを1つ提供しました!-)
Oliの答えと同様に、引数オブジェクトとデフォルト値を定義するオブジェクトを使用します。少し砂糖を入れて...
/**
* Updates an object's properties with other objects' properties. All
* additional non-falsy arguments will have their properties copied to the
* destination object, in the order given.
*/
function extend(dest) {
for (var i = 1, l = arguments.length; i < l; i++) {
var src = arguments[i]
if (!src) {
continue
}
for (var property in src) {
if (src.hasOwnProperty(property)) {
dest[property] = src[property]
}
}
}
return dest
}
/**
* Inherit another function's prototype without invoking the function.
*/
function inherits(child, parent) {
var F = function() {}
F.prototype = parent.prototype
child.prototype = new F()
child.prototype.constructor = child
return child
}
...これは少し良くすることができます。
function Field(kwargs) {
kwargs = extend({
required: true, widget: null, label: null, initial: null,
helpText: null, errorMessages: null
}, kwargs)
this.required = kwargs.required
this.label = kwargs.label
this.initial = kwargs.initial
// ...and so on...
}
function CharField(kwargs) {
kwargs = extend({
maxLength: null, minLength: null
}, kwargs)
this.maxLength = kwargs.maxLength
this.minLength = kwargs.minLength
Field.call(this, kwargs)
}
inherits(CharField, Field)
この方法の利点は何ですか?
- 好きなだけ引数を省略できます。1つの引数の値のみをオーバーライドする場合は、たとえば、
undefined
を明示的に渡す必要はなく、単にその引数を指定できます5つの引数があり、提案されている他のメソッドのいくつかを行う必要があるため、最後の引数のみをカスタマイズします。 - 別のオブジェクトから継承するオブジェクトのコンストラクタ関数を使用する場合、継承するオブジェクトのコンストラクタに必要な引数を受け入れるのは簡単です。これらの引数に名前を付ける必要はありません。コンストラクタシグネチャ、または独自のデフォルトを提供することもできます(上記のように、
CharField
がField
のコンストラクタを呼び出したときに、親オブジェクトのコンストラクタに実行させます)。 - 継承階層の子オブジェクトは、親コンストラクタの引数を適切にカスタマイズし、独自のデフォルト値を適用するか、特定の値が常に使用されるようにすることができます。
デフォルトを広範囲に使用している場合、これははるかに読みやすいようです:
function usageExemple(a,b,c,d){
//defaults
a=defaultValue(a,1);
b=defaultValue(b,2);
c=defaultValue(c,4);
d=defaultValue(d,8);
var x = a+b+c+d;
return x;
}
この関数をグローバルescopeで宣言するだけです。
function defaultValue(variable,defaultValue){
return(typeof variable!=='undefined')?(variable):(defaultValue);
}
使用パターン fruit = defaultValue(fruit、 'Apple');
* PS defaultValue
関数の名前を短い名前に変更できます。 default
はJavaScriptの予約語です。
ルースタイプチェック
書きやすいが、 0
、 ''
、 false
、 null
、および undefined
はデフォルト値に変換されますが、期待される結果ではない可能性があります。
function myFunc(requiredArg, optionalArg) {
optionalArg = optionalArg || 'defaultValue';
}
厳密な型チェック
より長いが、大部分のケースをカバーします。デフォルト値を誤って割り当てるのは、 undefined
をパラメーターとして渡すときだけです。
function myFunc(requiredArg, optionalArg) {
optionalArg = typeof optionalArg !== 'undefined' ? optionalArg : 'defaultValue';
}
引数変数の確認
すべてのケースをキャッチしますが、最も書きにくいです。
function myFunc(requiredArg, optionalArg1, optionalArg2) {
optionalArg1 = arguments.length > 1 ? optionalArg1 : 'defaultValue';
optionalArg2 = arguments.length > 2 ? optionalArg2 : 'defaultValue';
}
ES6
残念ながら、現時点ではブラウザのサポートが非常に貧弱です
function myFunc(requiredArg, optionalArg = 'defaultValue') {
}
ES2015 / ES6では、 $。extend()
または _。defaults()
を置き換えることができる Object.assign
を利用できます
function myFunc(requiredArg, options = {}) {
const defaults = {
message: 'Hello',
color: 'red',
importance: 1
};
const settings = Object.assign({}, defaults, options);
// do stuff
}
このようなデフォルト引数を使用することもできます
function myFunc(requiredArg, { message: 'Hello', color: 'red', importance: 1 } = {}) {
// do stuff
}
オプション変数の処理に関するいくつかの基本的なバリエーションを見ることに慣れています。時々、リラックスしたバージョンが便利です。
function foo(a, b, c) {
a = a || "default"; // Matches 0, "", null, undefined, NaN, false.
a || (a = "default"); // Matches 0, "", null, undefined, NaN, false.
if (b == null) { b = "default"; } // Matches null, undefined.
if (typeof c === "undefined") { c = "default"; } // Matches undefined.
}
変数 a
で使用される偽のデフォルトは、たとえば Backbone.js 。
Underscore ライブラリを使用している場合(素晴らしいライブラリです):
_.defaults(optionalArg, 'defaultValue');
この質問にたどり着き、 EcmaScript 2015のデフォルトパラメータを検索して、言及しました...
ES6 を使用すると、を実行できます。デフォルトパラメータ:
function doSomething(optionalParam = "defaultValue"){
console.log(optionalParam);//not required to check for falsy values
}
doSomething(); //"defaultValue"
doSomething("myvalue"); //"myvalue"
プロジェクト中に、オプションのパラメーターと設定を繰り返しすぎていることに気づいたので、型チェックを処理し、デフォルト値を割り当てるクラスを作成して、コードを読みやすく読みやすくしました。例を参照し、これがうまくいくかどうかを教えてください。
var myCar = new Car('VW', {gearbox:'automatic', options:['radio', 'airbags 2x']});
var myOtherCar = new Car('Toyota');
function Car(brand, settings) {
this.brand = brand;
// readable and adjustable code
settings = DefaultValue.object(settings, {});
this.wheels = DefaultValue.number(settings.wheels, 4);
this.hasBreaks = DefaultValue.bool(settings.hasBreaks, true);
this.gearbox = DefaultValue.string(settings.gearbox, 'manual');
this.options = DefaultValue.array(settings.options, []);
// instead of doing this the hard way
settings = settings || {};
this.wheels = (!isNaN(settings.wheels)) ? settings.wheels : 4;
this.hasBreaks = (typeof settings.hasBreaks !== 'undefined') ? (settings.hasBreaks === true) : true;
this.gearbox = (typeof settings.gearbox === 'string') ? settings.gearbox : 'manual';
this.options = (typeof settings.options !== 'undefined' && Array.isArray(settings.options)) ? settings.options : [];
}
このクラスの使用:
(function(ns) {
var DefaultValue = {
object: function(input, defaultValue) {
if (typeof defaultValue !== 'object') throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined') ? input : defaultValue;
},
bool: function(input, defaultValue) {
if (typeof defaultValue !== 'boolean') throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined') ? (input === true) : defaultValue;
},
number: function(input, defaultValue) {
if (isNaN(defaultValue)) throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined' && !isNaN(input)) ? parseFloat(input) : defaultValue;
},
// wrap the input in an array if it is not undefined and not an array, for your convenience
array: function(input, defaultValue) {
if (typeof defaultValue === 'undefined') throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined') ? (Array.isArray(input) ? input : [input]) : defaultValue;
},
string: function(input, defaultValue) {
if (typeof defaultValue !== 'string') throw new Error('invalid defaultValue type');
return (typeof input === 'string') ? input : defaultValue;
},
};
ns.DefaultValue = DefaultValue;
}(this));
@Paulの返信がダウン投票される理由はわかりませんが、 null
に対する検証は良い選択です。たぶん、より肯定的な例の方が意味があります:
JavaScriptでは、欠落したパラメーターは、初期化されていない宣言された変数のようなものです( var a1;
のみ)。また、等値演算子は未定義をnullに変換するため、値の型とオブジェクトの両方でうまく機能します。これがCoffeeScriptがオプションのパラメーターを処理する方法です。
function overLoad(p1){
alert(p1 == null); // Caution, don't use the strict comparison: === won't work.
alert(typeof p1 === 'undefined');
}
overLoad(); // true, true
overLoad(undefined); // true, true. Yes, undefined is treated as null for equality operator.
overLoad(10); // false, false
function overLoad(p1){
if (p1 == null) p1 = 'default value goes here...';
//...
}
ただし、最良のセマンティクスを得るには typeof variable === 'undefined'
の方が若干優れているという懸念があります。関数を実装する方法は基礎となるAPIの問題であるため、これを擁護するつもりはありません。 APIユーザーの関心を引くべきではありません。
また、残念ながらパラメータ名で動作しない in
演算子を使用して、引数が欠落していることを物理的に確認する唯一の方法もここに追加する必要があります。 arguments
。
function foo(a, b) {
// Both a and b will evaluate to undefined when used in an expression
alert(a); // undefined
alert(b); // undefined
alert("0" in arguments); // true
alert("1" in arguments); // false
}
foo (undefined);
undefinedのテストは不要であり、user568458が指摘したように、nullまたはfalseが渡されると提供されたソリューションが失敗するため、可能な限り堅牢ではありません。 APIのユーザーは、falseまたはnullがメソッドにそのパラメーターを避けるように強制すると考えるかもしれません。
function PaulDixonSolution(required, optionalArg){
optionalArg = (typeof optionalArg === "undefined") ? "defaultValue" : optionalArg;
console.log(optionalArg);
};
PaulDixonSolution("required");
PaulDixonSolution("required", "provided");
PaulDixonSolution("required", null);
PaulDixonSolution("required", false);
結果は次のとおりです。
defaultValue
provided
null
false
最後の2つは潜在的に悪いです。代わりに試してください:
function bulletproof(required, optionalArg){
optionalArg = optionalArg ? optionalArg : "defaultValue";;
console.log(optionalArg);
};
bulletproof("required");
bulletproof("required", "provided");
bulletproof("required", null);
bulletproof("required", false);
結果:
defaultValue
provided
defaultValue
defaultValue
これが最適でない唯一のシナリオは、ブール値または意図的なnullを意図したオプションのパラメーターが実際にある場合です。
ここに記載されているいくつかのオプションを試し、パフォーマンスをテストしました。現時点では、論理和が最速のようです。ただし、これは時間の経過とともに変化する可能性があります(異なるJavaScriptエンジンバージョン)。
これらは私の結果です(Microsoft Edge 20.10240.16384.0):
Function executed Operations/sec Statistics
TypeofFunction('test'); 92,169,505 ±1.55% 9% slower
SwitchFuntion('test'); 2,904,685 ±2.91% 97% slower
ObjectFunction({param1: 'test'}); 924,753 ±1.71% 99% slower
LogicalOrFunction('test'); 101,205,173 ±0.92% fastest
TypeofFunction2('test'); 35,636,836 ±0.59% 65% slower
このパフォーマンステストは、次のものに簡単に複製できます。 http://jsperf.com/optional-parameters-typeof-vs-switch/ 2
これはテストのコードです:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
Benchmark.prototype.setup = function() {
function TypeofFunction(param1, optParam1, optParam2, optParam3) {
optParam1 = (typeof optParam1 === "undefined") ? "Some default" : optParam1;
optParam2 = (typeof optParam2 === "undefined") ? "Another default" : optParam2;
optParam3 = (typeof optParam3 === "undefined") ? "Some other default" : optParam3;
}
function TypeofFunction2(param1, optParam1, optParam2, optParam3) {
optParam1 = defaultValue(optParam1, "Some default");
optParam2 = defaultValue(optParam2, "Another default");
optParam3 = defaultValue(optParam3, "Some other default");
}
function defaultValue(variable, defaultValue) {
return (typeof variable !== 'undefined') ? (variable) : (defaultValue);
}
function SwitchFuntion(param1, optParam1, optParam2, optParam3) {
switch (arguments.length - 1) { // <-- 1 is number of required arguments
case 0:
optParam1 = 'Some default';
case 1:
optParam2 = 'Another default';
case 2:
optParam3 = 'Some other default';
}
}
function ObjectFunction(args) {
var defaults = {
optParam1: 'Some default',
optParam2: 'Another default',
optParam3: 'Some other default'
}
args = $.extend({}, defaults, args);
}
function LogicalOrFunction(param1, optParam1, optParam2, optParam3) {
optParam1 || (optParam1 = 'Some default');
optParam2 || (optParam1 = 'Another default');
optParam3 || (optParam1 = 'Some other default');
}
};
</script>
これは私がやったことです:
function WhoLikesCake(options) {
options = options || {};
var defaultOptions = {
a : options.a || "Huh?",
b : options.b || "I don't like cake."
}
console.log('a: ' + defaultOptions.b + ' - b: ' + defaultOptions.b);
// Do more stuff here ...
}
次のように呼び出されます:
WhoLikesCake({ b : "I do" });
フォーク-
これらのソリューションや他のソリューションを確認した後、W3Schoolsのコードスニペットをベースとして使用して、いくつかのソリューションを試しました。以下で機能するものを見つけることができます。コメントアウトされた各アイテムも同様に機能し、個々のコメントを削除するだけで実験できるようになります。明確にするために、それは「アイカラー」です。定義されていないパラメーター。
function person(firstname, lastname, age, eyecolor)
{
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
this.eyecolor = eyecolor;
// if(null==eyecolor)
// this.eyecolor = "unknown1";
//if(typeof(eyecolor)==='undefined')
// this.eyecolor = "unknown2";
// if(!eyecolor)
// this.eyecolor = "unknown3";
this.eyecolor = this.eyecolor || "unknown4";
}
var myFather = new person("John", "Doe", 60);
var myMother = new person("Sally", "Rally", 48, "green");
var elem = document.getElementById("demo");
elem.innerHTML = "My father " +
myFather.firstname + " " +
myFather.lastname + " is " +
myFather.age + " with " +
myFather.eyecolor + " eyes.<br/>" +
"My mother " +
myMother.firstname + " " +
myMother.lastname + " is " +
myMother.age + " with " +
myMother.eyecolor + " eyes.";
function Default(variable, new_value)
{
if(new_value === undefined) { return (variable === undefined) ? null : variable; }
return (variable === undefined) ? new_value : variable;
}
var a = 2, b = "hello", c = true, d;
var test = Default(a, 0),
test2 = Default(b, "Hi"),
test3 = Default(c, false),
test4 = Default(d, "Hello world");
window.alert(test + "\n" + test2 + "\n" + test3 + "\n" + test4);
これが私の解決策です。これにより、必要なパラメータを残すことができます。オプションのパラメーターの順序は重要ではなく、カスタム検証を追加できます。
function YourFunction(optionalArguments) {
//var scope = this;
//set the defaults
var _value1 = 'defaultValue1';
var _value2 = 'defaultValue2';
var _value3 = null;
var _value4 = false;
//check the optional arguments if they are set to override defaults...
if (typeof optionalArguments !== 'undefined') {
if (typeof optionalArguments.param1 !== 'undefined')
_value1 = optionalArguments.param1;
if (typeof optionalArguments.param2 !== 'undefined')
_value2 = optionalArguments.param2;
if (typeof optionalArguments.param3 !== 'undefined')
_value3 = optionalArguments.param3;
if (typeof optionalArguments.param4 !== 'undefined')
//use custom parameter validation if needed, in this case for javascript boolean
_value4 = (optionalArguments.param4 === true || optionalArguments.param4 === 'true');
}
console.log('value summary of function call:');
console.log('value1: ' + _value1);
console.log('value2: ' + _value2);
console.log('value3: ' + _value3);
console.log('value4: ' + _value4);
console.log('');
}
//call your function in any way you want. You can leave parameters. Order is not important. Here some examples:
YourFunction({
param1: 'yourGivenValue1',
param2: 'yourGivenValue2',
param3: 'yourGivenValue3',
param4: true,
});
//order is not important
YourFunction({
param4: false,
param1: 'yourGivenValue1',
param2: 'yourGivenValue2',
});
//uses all default values
YourFunction();
//keeps value4 false, because not a valid value is given
YourFunction({
param4: 'not a valid bool'
});
-
arg || 「デフォルト」
は素晴らしい方法であり、90%のケースで機能します -
「偽」の値を渡す必要がある場合は失敗します
-
false
-
0
-
NaN
-
&quot;&quot;
これらの場合、もう少し冗長になり、
undefined
を確認する必要があります。
-
-
また、最初にオプションの引数がある場合は注意してください。すべての引数の型に注意する必要があります
optionalArgが偽である場合はすべて、defaultValueになります。
function myFunc(requiredArg, optionalArg) {
optionalArg = optionalArg || 'defaultValue';
console.log(optionalArg);
// Do stuff
}
myFunc(requiredArg);
myFunc(requiredArg, null);
myFunc(requiredArg, undefined);
myFunc(requiredArg, "");
myFunc(requiredArg, 0);
myFunc(requiredArg, false);
6つすべてが偽であるため、上記のすべてのログdefaultValue。ケース4、5、6の場合、optionalArgをdefaultValueとして設定する必要はありませんが、偽であるため設定されます。
間違っている場合は修正してください
function myFunction(Required,Optional)
{
if (arguments.length<2) Optional = "Default";
//Your code
}
これらは、typeof演算子バージョンよりも短いものです。
function foo(a, b) {
a !== undefined || (a = 'defaultA');
if(b === undefined) b = 'defaultB';
...
}
ArgueJS を次のように使用することをお勧めします。
function myFunc(){
arguments = __({requiredArg: undefined, optionalArg: [undefined: 'defaultValue'})
//do stuff, using arguments.requiredArg and arguments.optionalArg
// to access your arguments
}
undefined
を、受け取る予定の引数のタイプに置き換えることもできます。例:
function myFunc(){
arguments = __({requiredArg: Number, optionalArg: [String: 'defaultValue'})
//do stuff, using arguments.requiredArg and arguments.optionalArg
// to access your arguments
}
を使用することを決定する前に、提供された引数のすべての 偽の種類 を処理するための最も安全な方法のようです default -呼び出された関数にオプション引数が存在するかどうかを確認します。
引数が欠落している場合でも作成されない引数オブジェクトメンバーの作成に依存しているため、宣言される可能性があるにもかかわらず、次のように関数を記述できます。
function myFunc(requiredArg, optionalArg){
optionalArg = 1 in arguments ? optionalArg : 'defaultValue';
//do stuff
}
この動作の利用: 関数がそのプロシージャで必要な特定の値を取得することを確認する必要があるときはいつでも、引数リストの欠損値を任意にかつ明示的に安全にチェックできます。
次のデモコードでは、 typeless および valueless undefined をデフォルト値として意図的に配置します。 0 falseなどの偽の引数値で失敗するかどうか、または期待どおりに動作するかどうかを判断できます。
function argCheck( arg1, arg2, arg3 ){
arg1 = 0 in arguments || undefined;
arg2 = 1 in arguments || false;
arg3 = 2 in arguments || 0;
var arg4 = 3 in arguments || null;
console.log( arg1, arg2, arg3, arg4 )
}
今、いくつかの偽の引数値をチェックして、それらの存在が正しく検出され、 true と評価されるかどうかを確認します:
argCheck( "", 0, false, null );
>> true true true true
は、-期待される引数値の認識に失敗しなかったことを意味します。 ここでは、すべての引数が欠落しているチェックがあり、アルゴによれば、それらが falsy であってもデフォルト値を取得する必要があります。
argCheck( );
>> undefined false 0 null
ご覧のとおり、引数 arg1、arg2、arg3 および未宣言の arg4 は、正確な default 値、注文どおり。 確実に機能するようになったため、最初の例のように実際に使用できる関数を書き換えることができます: if または三元条件。
オプションの引数が複数ある関数では、ループスルーにより、少し節約できたかもしれません。しかし、引数 names は、値が指定されていない場合は初期化されないため、プログラムでデフォルト値を書き込んだとしても、名前でそれらにアクセスできなくなります。それらにアクセスするには arguments [index] を使用しますが、これは無駄なコードを読みやすくします。
しかし、特定のコーディング状況では完全に受け入れられるかもしれないこの不便さは別として、複数の任意の数の引数のデフォルトには別の未解決の問題があります。これはバグと見なされるべきであり、バグと見なされるべきです。引数をスキップすることはできなくなりました。値を与えずに次のような構文でできた可能性があるためです。
argCheck("a",,22,{});
投げるから!このため、引数を特定の falsy タイプのデフォルト値に置き換えることはできません。 argumentsオブジェクトは配列に似たオブジェクトであり、ネイティブまたはデフォルトでこの構文と規則をそのままサポートすることが期待されているため、これは愚かです!
この近視眼的な決定のため、次のような関数を書くことはもう望めません。
function argCheck( ) {
var _default = [undefined, 0, false, null ],
_arg = arguments;
for( var x in _default ) {
x in _arg ? 1 : _arg[x] = _default[x];
}
console.log( _arg[0],_arg[1],_arg[2],_arg[3] );
}
その場合、目的の型の各デフォルト値を引数の行に書き込み、少なくともargs.indexによってそれらにアクセスできるようになります。
たとえば、この関数呼び出しは次のようになります。
argCheck();
>>undefined 0 false null
引数値のデフォルト配列で定義されている。 ただし、次のことは引き続き可能です。
argCheck({})
>>Object { } 0 false null
argCheck({}, [])
>>Object { } Array [ ] false null
しかし、残念ながらそうではありません:
argCheck("a",,,22);
>>SyntaxError: expected expression, got ','
それ以外の場合、ログを記録します:
>>a 0 false 22
しかし、それはより良い世界です! ただし、元の質問の場合、最上位の関数で十分です。 例:
function argCheck( arg, opt ) {
1 in arguments ? 1 : opt = "default";
console.log( arg, opt );
}
p.s .:引数の入力中に選択したデフォルトの types を保存しないで申し訳ありません。
function foo(requiredArg){
if(arguments.length>1) var optionalArg = arguments[1];
}