web-dev-qa-db-ja.com

Javascript:プロトタイプメソッドをforループに隠しますか?

それで、Arrayクラスにいくつかのプロトタイプメソッドを追加したとしましょう。



Array.prototype.containsKey = function(obj) {
    for(var key in this)
        if (key == obj) return true;
    return false;
}

Array.prototype.containsValue = function(obj) {
    for(var key in this)
        if (this[key] == obj) return true;
    return false;
}

次に、連想配列を作成し、そのキーをループしようとします。



var arr = new Array();
arr['One'] = 1;
arr['Two'] = 2;
arr['Three'] = 3;

for(var key in arr)
   alert(key);

これは5つのアイテムを返します:

-1つ
-2つ
-3つ
-containsKey 
-containsValue 

しかし、私は(期待しますか?)3つだけ欲しいです。私はこれに間違って近づいていますか?プロトタイプメソッドを「隠す」方法はありますか?または私は別のことをする必要がありますか?

43

JavaScriptの hasOwnProperty メソッドを使用して、次のようにループでこれを実現できます。

for(var key in arr) {
    if (arr.hasOwnProperty(key)) {
        ...
    }
}

参照: このYUIブログ記事

48
Kirtan

プロトタイプメソッドを列挙できないようにすることで、もう一方の端から目的の結果を得ることができます。

Object.defineProperty(Array.prototype, "containsKey", {
  enumerable: false,
  value: function(obj) {
      for(var key in this)
        if (key == obj) return true;
      return false;
    }
});

これは通常、メソッド定義を制御できる場合、特にライブラリコード開発で一般的な前提である、他の人がコードを呼び出す方法を制御できない場合に、より適切に機能します。

47
abbr

Javascriptは、あなたが思っているように連想配列をサポートしていません。 http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful

for(var i in ..は、オブジェクトのすべてのプロパティを取得します(配列は単なる別のオブジェクトです)。そのため、プロトタイプを作成した他のオブジェクトが表示されます。

記事が示唆しているように、オブジェクトを使用する必要があります。


var assoc = {'One' : 1, 'Two' : 2};
assoc['Three'] = 3;

for(var key in assoc)
   alert(key+' => '+assoc[key]);
4
rezzif

あなたはこれを行うことができます:

for(var key in arr)
{
   if (typeof(arr[key]) == "function")
      continue;
   alert(key);
}

しかし、それはお粗末な回避策です

2
user19302

メソッド1:use Object.keys (プロトタイプのプロパティを返さない)&loop

Object.keys(arr); // ['One', 'Two', 'Three']
Object.keys(arr).forEach(key => console.log(key))

メソッド2hasOwnProperty forループ内。

 for(var key in arr) {
   if (arr.hasOwnProperty(key)) {
     ...
   }
 }
1
cacoder

JavaScript配列を高速で反復するには、forまたはwhileループを使用します。 Nicholas Zakasは、Tech Talk Speed Up Your JavaScript で、配列を反復処理するための最もパフォーマンスの高いオプションについて説明しています。

あなたの最善の策はおそらく次のようなものです:

for (var i = collection.length - 1; i >= 0; i--) {
  if (obj == collection[i]) return true;
}

このアプローチは、いくつかの理由で最適に実行されます。

  • 単一のローカル変数のみが割り当てられます
  • コレクションのlengthプロパティは、ループの初期化時に1回だけアクセスされます
  • 反復ごとに、ローカルは定数(i >= 0)別の変数の代わりに
0
Duncan Beevers