0

これは、より一般的なプラクティスの質問です。

私が扱っている言語は Javascript です。多くの変数を持つオブジェクトを取得する関数があります (10 個の変数のみです)。この関数が必要なすべての変数を取得し、それらがすべて設定されていることを確認する最善の方法は何ですか?

私は知っています、私は知っています、なぜifステートメントを使用しないのですか。これは、if ステートメントの大きな塊です。私がプログラマーとして成長するにつれて、これが最善の方法ではない可能性があることはわかっています。私は実際にショートカットを探しています。大量の変数の存在と空白でない値をどのようにチェックしますか?

4

4 に答える 4

1

まず第一に、これらの言語の理解を深め、正しい用語を学ぶ必要があります。

  1. 「Javascript」という名前の (単一の) 言語はまったくありません。 ここでは暗黙的にいくつかの言語を使用しています (ランタイム環境によって異なります)。これらはすべて ECMAScript 実装であり、そのうちの1 つNetscape/Mozilla JavaScript (Firefox などの Mozilla ベースのソフトウェア)です。
  2. オブジェクトには変数がなく、プロパティがあります( : キーではありません) グローバル コード、関数コード、およびevalコードは変数を持つことができます。それは異なる(しかし類似した) 概念です。
  3. 関数はオブジェクトを取得していません。オブジェクトへの参照が引数として渡されています。

プログラマーは、ループ内で反復タスクを実行できることを既に知っているはずです。ECMAScript 実装で関連するステートメントはforfor- inwhileおよびdoです。したがって、複数のステートメントを記述する必要はありません。if

オブジェクトのプロパティには 2 つの方法でアクセスできます。ここpropertyで、 はプロパティ名です。

  1. ドット表記:obj.property
  2. ブラケット表記:obj["property"]

プロパティ名が識別子である場合、つまり、特定の命名規則に従っている場合、2 番目のものは最初のものと同等です。プロパティ名が識別子でない場合、または変数である場合は、2 番目のものを使用する必要があります。これは、すべてのプロパティが文字列値であることも示しています。したがって、プロパティの名前を変数または別のプロパティの値として格納し、プロパティ アクセサーで変数またはプロパティにアクセスできます。以下では、プロパティ名 ( property) が変数に格納され、変数から使用されます。

var propertyName = "property";
obj[propertyName]

これをループと組み合わせると、オブジェクトの特定のプロパティを反復処理できます。残念ながら、これまでに提示されたソリューションには 2 つの点で欠陥があります。for-inステートメントは、オブジェクトの列挙可能なプロパティに対してのみ反復し、任意の順序で反復します。さらに、列挙可能な継承hasOwnProperty()されたプロパティも反復処理します (これが、1 つのソリューションで呼び出しが必要な理由です)。

定義された順序でオブジェクトの特定のプロパティのみを反復処理する簡単で確実かつ効率的な方法は、次のようになります。

var propertyNames = ['name1', 'name2', 'name3'];
for (var i = 0, len = propertyNames.length; i < len; ++i)
{
  /* … */ myObject[propertyNames[i]] /* … */
}

これは、配列データ構造をカプセル化するインスタンスpropertyNamesを参照するため機能します。Array配列の要素は、Array0 ~ 65535 (2 32 -1) の整数インデックスを持つインスタンスのプロパティです。インデックスは識別子ではないため (10 進数で始まる)、ブラケット プロパティ アクセサー構文を使用する必要があります (これを誤解して、すべての ECMAScript オブジェクトを「配列」と呼び、「連想配列」や「配列」と呼ぶ人もいます) […]。オペレーター")。したがって、propertyNames[i]各反復で配列の要素の値が評価され、毎回i1 ずつ増加します。その結果、myObject[propertyNames[i]]各ループでその名前のプロパティにアクセスします。

ここで、プロパティが設定されているかどうかを確認するには、その意味を定義する必要があります。存在しないプロパティにアクセスすると、undefined値が返されます (エラーにはなりません)。ただし、既存のプロパティもundefinedその値として値を持つ場合があります。

「設定されていない」とは、オブジェクトがプロパティを持っていない (ただし継承する可能性がある) ことを意味する場合hasOwnProperty()、Mahn のソリューションで使用されているように使用する必要があります。

「設定されていない」がオブジェクトにプロパティがなく、それを継承しないことを意味する場合、オブジェクトがホスト オブジェクトでない場合は、演算子を使用する必要があります(演算inが指定れていないため)。in

if (propertyNames[i] in obj)

「設定されていない」とは、オブジェクトがプロパティを持っているか継承しているが、プロパティにundefined値があるか、オブジェクトがプロパティを持っていないか継承していないことを意味する場合typeof、Bob Davies と aetaur のソリューションで使用されている演算子を使用する必要があります (ただし、後者を使用Array.prototype.every()する方法はそのままでは互換性が低くなります; その方法は ECMAScript Edition 5 より前では指定されておらず、IE/JScript < 9 では使用できません)。

ECMAScript Edition 5.x には 3 番目のオプションがあります。このObject.keys()メソッドは、(その名前にもかかわらず)Array引数の継承されていないすべてのプロパティの名前を保持するインスタンスへの参照を返します。

var propertyNames = Object.keys(obj);

/* continue as described above */

Object.keys()このアルゴリズムは頻繁に役立つため、組み込みでない場合はエミュレートすることをお勧めします。

于 2012-06-30T16:05:12.280 に答える
1

これは、バリデーションを処理するための非常に巧妙な方法です。私は通常、フォーム入力の必須フィールドをチェックするときにこれを使用します。

var theObj = { /* object loaded from server */ }

function checkTheObj(testObj)
{
  var requiredKeys = ['key1', 'key2', 'key3'];
  for(var keyPos = 0; keyPos < requiredKeys.length; keyPos++)
  {
    if(typeof(testObj[requiredKeys[keyPos]]) == 'undefined')
    {
      return false;
    }
  }
  return true;
}

if(checkTheObj(theObj))
{
  //do stuff
}

もちろん、これを微調整して、最初に欠落しているフィールドを伝える例外を返すかスローすることができます (または内部配列を使用して、欠落しているすべてのフィールドのリストを返します)。

于 2012-06-30T13:55:41.810 に答える
1
function objectHas(obj, properties) {
    var len = properties.length
    for (var i=0; i<len; i++) {
        if (i in properties) {
            if((!obj.hasOwnProperty(properties[i])) || (!obj.propertyIsEnumerable(properties[i]))) {
                return false;
            }
        }
    }
    return true;
}

使用法:

if(objectHas(user, ["email", "password", "phone"])) {
    console.log("awesome");
}

シンプルですが、機能します。

編集: 理想的な世界では、オブジェクト プロトタイプを拡張して、if(object.has(["a", "b", "c"]))などのより適切な構文にすることができますが、明らかにオブジェクト プロトタイプを拡張することは化身です。悪のので、関数がしなければならないでしょう:)

于 2012-06-30T14:02:38.157 に答える
0

variableNameList(必要な変数名のリスト) のすべての変数が object に設定されている場合、この式は true を返しoます。

variableNameList.every(function(varName){ return typeof o[varName] !== 'undefined'; });

_.allnative の代わりにアンダースコア関数を使用しevery、の_.isUndefined代わりにアンダースコアを使用できますtypeof ...

于 2012-06-30T14:09:48.340 に答える