引数がJavaScript関数に渡されたかどうかを判断する2つのメソッドを見てきました。ある方法が他の方法より優れているのか、それとも使用するのが悪いのか疑問に思っていますか?
function Test(argument1, argument2) {
if (Test.arguments.length == 1) argument2 = 'blah';
alert(argument2);
}
Test('test');
または
function Test(argument1, argument2) {
argument2 = argument2 || 'blah';
alert(argument2);
}
Test('test');
私の知る限り、どちらも同じ結果になりますが、本番環境で使用するのは最初の1つだけです。
Tom で述べた別のオプション:
function Test(argument1, argument2) {
if(argument2 === null) {
argument2 = 'blah';
}
alert(argument2);
}
Juanのコメントによると、Tomの提案を次のように変更する方が良いでしょう。
function Test(argument1, argument2) {
if(argument2 === undefined) {
argument2 = 'blah';
}
alert(argument2);
}
JQueryを使用している場合、ニース(特に複雑な状況)の1つのオプションは、 jQueryのextendメソッド を使用することです。
function foo(options) {
default_options = {
timeout : 1000,
callback : function(){},
some_number : 50,
some_text : "hello world"
};
options = $.extend({}, default_options, options);
}
関数を呼び出すと、次のようになります。
foo({timeout : 500});
オプション変数は次のようになります。
{
timeout : 500,
callback : function(){},
some_number : 50,
some_text : "hello world"
};
これは、テストを見つける数少ないケースの1つです。
if(! argument2) {
}
非常にうまく機能し、正しい意味を構文的に伝えます。
(他の意味を持つargument2
の正当なnull値を許可しないという同時制限があるが、それはreally紛らわしい。)
編集:
これは、緩やかに型付けされた言語と強く型付けされた言語の文体的な違いの実に良い例です。 JavaScriptがスペードで提供するスタイルオプション。
私の個人的な好み(他の好みに対する批判はありません)はミニマリズムです。一貫性があり簡潔である限り、コードが言う必要が少ないほど、他の誰かが私の意味を正しく推測するために理解する必要が少なくなります。
その好みの1つの含意は、私はしたくない-それを便利だとは思わない-タイプ依存性テストの束を積み上げます。代わりに、コードが意味するものを意味するようにします。そして、私が本当にテストする必要があるものだけをテストします。
他の人々のコードで私が見つけた悪化の1つは、彼らがより大きな文脈で、彼らがテストしているケースに実際に走ることを期待するかどうかを理解する必要があることです。または、可能性のあるものすべてをテストしようとしている場合、コンテキストを十分に予測できない可能性があります。つまり、自信を持って何かをリファクタリングまたは変更する前に、両方向に徹底的に追跡する必要があります。私は、彼らが必要とされる状況を予見したので、それらのさまざまなテストを実施した可能性が高いと考えています(そして、それは通常私には明らかではありません)。
(これらの人々が動的言語を使用する方法の深刻なマイナス面を考えます。多くの場合、人々はすべての静的テストをあきらめたくなく、それを偽造することになります。)
これは、包括的なActionScript 3コードとエレガントなjavascriptコードを比較したときに最も目立って見ました。 AS3はjsの3倍または4倍である可能性があり、コーディング決定の数(3-4X)だけのために、少なくとも信頼性は良くないと思います。
あなたが言うように、Shog9、YMMV。 :D
大きな違いがあります。いくつかのテストケースを設定しましょう。
var unused; // value will be undefined
Test("test1", "some value");
Test("test2");
Test("test3", unused);
Test("test4", null);
Test("test5", 0);
Test("test6", "");
最初に説明した方法では、2番目のテストのみがデフォルト値を使用します。 2番目のメソッドは最初のメソッドを除くすべてをデフォルトにします(JSはundefined
、null
、0
、および""
をブール値false
に変換します。そして、Tomのメソッドを使用する場合、4番目のテストのみがデフォルトを使用します!
どの方法を選択するかは、意図する動作によって異なります。 argument2
にundefined
以外の値を使用できる場合は、おそらく最初のバリエーションを使用する必要があります。非ゼロ、非ヌル、非空の値が必要な場合は、2番目の方法が理想的です。実際、このような広範囲の値を考慮から迅速に排除するためによく使用されます。
url = url === undefined ? location.href : url;
ES6(ES2015)では、 デフォルトのパラメーター を使用できます
function Test(arg1 = 'Hello', arg2 = 'World!'){
alert(arg1 + ' ' +arg2);
}
Test('Hello', 'World!'); // Hello World!
Test('Hello'); // Hello World!
Test(); // Hello World!
申し訳ありませんが、まだコメントできませんので、トムの答えに答えるには... javascript(undefined!= null)== false
!!
演算子を使用しないのはなぜですか?変数の前に置かれたこの演算子は、ブール値に変換します(十分に理解している場合)。したがって、!!undefined
および!!null
(さらに、!!NaN
も非常に興味深い場合があります)はfalse
を返します。
次に例を示します。
function foo(bar){
console.log(!!bar);
}
foo("hey") //=> will log true
foo() //=> will log false
オプションのプロパティのオブジェクトを使用して関数を呼び出すことにより、引数の検出にアプローチすると便利です。
function foo(options) {
var config = { // defaults
list: 'string value',
of: [a, b, c],
optional: {x: y},
objects: function(param){
// do stuff here
}
};
if(options !== undefined){
for (i in config) {
if (config.hasOwnProperty(i)){
if (options[i] !== undefined) { config[i] = options[i]; }
}
}
}
}
場合によっては、特にgetterおよびsetterとして関数を使用している場合は、タイプを確認することもできます。次のコードはES6です(EcmaScript 5以前では実行されません)。
class PrivateTest {
constructor(aNumber) {
let _aNumber = aNumber;
//Privileged setter/getter with access to private _number:
this.aNumber = function(value) {
if (value !== undefined && (typeof value === typeof _aNumber)) {
_aNumber = value;
}
else {
return _aNumber;
}
}
}
}
パラメータが関数に渡されるかどうかを見つけるための巧妙な方法 があります。以下の例をご覧ください。
this.setCurrent = function(value) {
this.current = value || 0;
};
これが必要なのは、value
の値が存在しない/渡されない場合、0に設定することです。
かっこいいね