web-dev-qa-db-ja.com

引数がJavaScript関数に送信されないかどうかを判断する最善の方法

引数が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);
}
226
Darryl Hein

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"
};
16
Greg Tatum

これは、テストを見つける数少ないケースの1つです。

if(! argument2) {  

}

非常にうまく機能し、正しい意味を構文的に伝えます。

(他の意味を持つargument2の正当なnull値を許可しないという同時制限があるが、それはreally紛らわしい。)

編集:

これは、緩やかに型付けされた言語と強く型付けされた言語の文体的な違いの実に良い例です。 JavaScriptがスペードで提供するスタイルオプション。

私の個人的な好み(他の好みに対する批判はありません)はミニマリズムです。一貫性があり簡潔である限り、コードが言う必要が少ないほど、他の誰かが私の意味を正しく推測するために理解する必要が少なくなります。

その好みの1つの含意は、私はしたくない-それを便利だとは思わない-タイプ依存性テストの束を積み上げます。代わりに、コードが意味するものを意味するようにします。そして、私が本当にテストする必要があるものだけをテストします。

他の人々のコードで私が見つけた悪化の1つは、彼らがより大きな文脈で、彼らがテストしているケースに実際に走ることを期待するかどうかを理解する必要があることです。または、可能性のあるものすべてをテストしようとしている場合、コンテキストを十分に予測できない可能性があります。つまり、自信を持って何かをリファクタリングまたは変更する前に、両方向に徹底的に追跡する必要があります。私は、彼らが必要とされる状況を予見したので、それらのさまざまなテストを実施した可能性が高いと考えています(そして、それは通常私には明らかではありません)。

(これらの人々が動的言語を使用する方法の深刻なマイナス面を考えます。多くの場合、人々はすべての静的テストをあきらめたくなく、それを偽造することになります。)

これは、包括的なActionScript 3コードとエレガントなjavascriptコードを比較したときに最も目立って見ました。 AS3はjsの3倍または4倍である可能性があり、コーディング決定の数(3-4X)だけのために、少なくとも信頼性は良くないと思います。

あなたが言うように、Shog9、YMMV。 :D

13
dkretz

大きな違いがあります。いくつかのテストケースを設定しましょう。

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はundefinednull0、および""をブール値falseに変換します。そして、Tomのメソッドを使用する場合、4番目のテストのみがデフォルトを使用します!

どの方法を選択するかは、意図する動作によって異なります。 argument2undefined以外の値を使用できる場合は、おそらく最初のバリエーションを使用する必要があります。非ゼロ、非ヌル、非空の値が必要な場合は、2番目の方法が理想的です。実際、このような広範囲の値を考慮から迅速に排除するためによく使用されます。

7
Shog9
url = url === undefined ? location.href : url;
6
Lamy

ES6(ES2015)では、 デフォルトのパラメーター を使用できます

function Test(arg1 = 'Hello', arg2 = 'World!'){
  alert(arg1 + ' ' +arg2);
}

Test('Hello', 'World!'); // Hello World!
Test('Hello'); // Hello World!
Test(); // Hello World!
4
Andriy2

申し訳ありませんが、まだコメントできませんので、トムの答えに答えるには... javascript(undefined!= null)== false

3
Luca Matteis

!!演算子を使用しないのはなぜですか?変数の前に置かれたこの演算子は、ブール値に変換します(十分に理解している場合)。したがって、!!undefinedおよび!!null(さらに、!!NaNも非常に興味深い場合があります)はfalseを返します。

次に例を示します。

function foo(bar){
    console.log(!!bar);
}

foo("hey") //=> will log true

foo() //=> will log false
2
RallionRl

オプションのプロパティのオブジェクトを使用して関数を呼び出すことにより、引数の検出にアプローチすると便利です。

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]; }
            }
        }
    }
}
2
1nfiniti

場合によっては、特に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;
            }
        }
    }
}
1
nbloqs

パラメータが関数に渡されるかどうかを見つけるための巧妙な方法 があります。以下の例をご覧ください。

this.setCurrent = function(value) {
  this.current = value || 0;
};

これが必要なのは、valueの値が存在しない/渡されない場合、0に設定することです。

かっこいいね

1
student