17

Array.prototype と Object.prototype でヘルパー メソッドを定義したいと考えています。私の現在の計画は、次のようなことをすることです:

Array.prototype.find = function(testFun) {
   // code to find element in array
};

私がこれを行うことができるように:

var arr = [1, 2, 3];
var found = arr.find(function(el) { return el > 2; });

正常に動作しますが、ループ内で配列をfor inループすると、メソッドが値として表示されます。

for (var prop in arr) { console.log(prop); }
// prints out:
// 1
// 2
// 3
// find

これは、値を表示するだけに依存している他の人を台無しにしfor inます (特にオブジェクトで)。それ以降のバージョンの javascript には、配列に組み込まれた .map および .filter 関数がありますが、それらはfor inループには表示されません。for inループに表示されないようなメソッドをさらに作成するにはどうすればよいですか?

4

4 に答える 4

24

とても簡単です: Arrays で for-in ループを使用しないでください。そうする他のすべての人を非難してください-開発中に彼らに伝えるための素晴らしいスニペットがあります.

もちろん、ジェネリック関数で列挙を行い、配列、プレーン オブジェクト、またはカスタム プロトタイプを持つオブジェクトのいずれを取得するかわからない場合は、次のhasOwnPropertyように使用できます。

for (var prop in anyObj )
    if (Object.prototype.hasOwnProperty.call(anyObj, prop))
        // do something

関数を取得するために を明示的に使用していることに注意してくださいObject.prototype- それを上書きするオブジェクト (特にデータ マップでは、値は関数でさえない可能性があります)、それをサポートしないオブジェクト、または Object.prototype から継承しないオブジェクトが存在する可能性があります。まったく。こちらもご覧ください

それでも、この問題を認識しているスクリプト作成者だけが、すべての for-in-loop をフィルター処理します (推奨されるためだけに実行する人もいます) 。そしてほとんど間違っています。代わりに for-loop 配列反復を使用する必要がありました。しかし、私たちの問題は、それを知らない著者です。

興味深いが、Mozilla のみのアプローチは、ここで示されている__iterate__ように、 を介して配列の列挙の動作を上書きすることです。

幸いなことに、EcmaScript 5.1 では、プロパティを列挙不可に設定できます。もちろん、これは古いブラウザではサポートされていませんが、わざわざする必要はありません。いずれにせよ、すべてのクールな高次配列にはes5-shimsを使用する必要があります:-) 次のdefinePropertyように使用します。

Object.defineProperty(Array.prototype, "find", {
    enumerable: false,
    writable: true,
    value: function(testFun) {
        // code to find element in array
    }
});
于 2012-11-08T20:06:08.657 に答える
6

制限に応じて:

// In EcmaScript 5 specs and browsers that support it you can use the Object.defineProperty
// to make it not enumerable set the enumerable property to false
Object.defineProperty(Array.prototype, 'find', {
    enumerable: false,  // this will make it not iterable
    get: function(testFun) {
       // code to find element in array
    };
});

Object.definePropertyの詳細については、 https: //developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/definePropertyをご覧ください。

于 2012-11-08T19:54:13.437 に答える
0

以下を確認する必要があるためですhasOwnProperty

for (var prop in arr) { 
  if (arr.hasOwnProperty(prop)) { 
    console.log(prop) 
  }
}

これで 1、2、3 がログに記録されます。

于 2012-11-08T19:38:42.253 に答える