列挙可能とはどういう意味ですか?


151

MDNのfor..inページに誘導されましたに「for..inはオブジェクトの列挙可能なプロパティを反復処理する」と表示されました。

次に、「列挙可能なプロパティはfor..inループで反復できるプロパティです」と記載されているプロパティの列挙可能性と所有権のページに行きました。

辞書では、列挙可能を可算として定義していますが、それが何を意味するのかを実際に視覚化することはできません。列挙可能なものの例を入手できますか?


何を理解してfor-inいますか?

for..inの回答から、オブジェクトのすべての列挙可能なプロパティをforステートメントで使用できるようになりました
Patrick

6
最も単純な意味は次のとおりです。プロパティがfor inループによって生成されるかどうか(詳細を知りたくない、または気にしない人のために))
Tomasz Racia

回答:


158

列挙可能なプロパティとは、for..inループ中に含めることができ、ループ中にアクセスできるプロパティ(または、プロパティの同様の反復、Object.keys())です。

プロパティが列挙可能として識別されない場合、ループはそれがオブジェクト内にあることを無視します。

var obj = { key: 'val' };

console.log('toString' in obj); // true
console.log(typeof obj.toString); // "function"

for (var key in obj)
    console.log(key); // "key"

プロパティは、それ自体の[[Enumerable]]属性によって列挙可能かどうかによって識別されます。これは、プロパティの記述子の一部として表示できます。

var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar');

console.log(descriptor.enumerable); // true
console.log(descriptor.value);      // 1

console.log(descriptor);
// { value: 1, writable: true, enumerable: true, configurable: true }

for..inループは、オブジェクトのプロパティ名を反復処理します。

var foo = { bar: 1, baz: 2};

for (var prop in foo)
    console.log(prop); // outputs 'bar' and 'baz'

ただし、そのステートメントを評価するのconsole.log(prop);は、この場合、[[Enumerable]]属性がであるプロパティに対してのみですtrue

特に継承から、オブジェクトにはさらに多くのプロパティがあるため、この条件が整っています。

console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]

これらの各プロパティはまだオブジェクトに存在します

console.log('constructor' in foo); // true
console.log('toString' in foo);    // true
// etc.

しかし、for..in列挙できないため、ループによってスキップされます。

var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');

console.log(descriptor.enumerable); // false

したがって、for..inループに表示されないため、コンストラクタプロパティは列挙できません。オブジェクトからそれぞれconsole.logを実行できたので、barやbazなどのプロパティの名前は列挙できますか?
Patrick

5
これは完全に正しいわけではありませんBut, they are skipped (or not counted) by the for..in loop because they are not enumerable。のプロパティObject.prototypeは、プロトタイプチェーンの上位にあるため、実際には無視されます。列挙できないためではありません。どちらもないgetOwnPropertyNames()keys()、オブジェクト自体ではないプロパティを表示します。補足として、組み込みプロパティの多くは列挙できないためで表示されないことは事実keys()ですが、プロトタイプチェーンをトラバースする場合は、追加のコードを記述する必要があります。
マグナス

文字通り、列挙可能とは数えられることを意味します
クリスチャンマシュー

49

を介してオブジェクトを作成する場合myObj = {foo: 'bar'}、すべてのプロパティが列挙可能です。それで、尋ねるのがより簡単な質問は、列挙できないものは何ですか?特定のオブジェクトにはいくつかの列挙不可能なプロパティがあります。たとえば、Object.getOwnPropertyNames([])([]で列挙可能かどうかにかかわらず、すべてのプロパティの配列を返す)を呼び出すと、配列の列挙['length']不可能なプロパティ 'length'を含むが返されます。 。

を呼び出すことで、独自の列挙できないプロパティを作成できますObject.defineProperty

var person = { age: 18 };
Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false });

person.name; // 'Joshua'
for (prop in person) {
  console.log(prop);
}; // 'age'

この例では、JavaScriptの列挙不可能なプロパティを多用していますが、オブジェクトが列挙されていることを示しています。プロパティは、書き込み可能、​​構成可能、または列挙可能である場合とそうでない場合があります。John Resigは、ECMAScript 5のオブジェクトとプロパティの範囲でこれについて説明しています

また、プロパティを非列挙型にする理由について、Stack Overflowの質問があります


うーん、賛成投票と反対投票の両方。確かに、この回答について投票する価値があるものがあれば、ここにコメントを追加してください。
カーペリアム2013

1
別の答えはこれを書いた:var o = {}; o ['foo'] = 0; //列挙可能、通常のObject.defineProperty(o、 'bar'、{value:1}); //数え切れない、奇妙な理由列挙型を明示的に追加する:false?
Patrick

5
@Patrick、ここに部分的に含めたのは、例からそれがオプションであることを明確にするためですが、オーディエンスによっては、明示的にすることは、コードを読んでいる誰にとっても明確になるように確固たる決定である場合があります。
カーペリアム2013

@carpeliamこの短くて非常に明確な説明に感謝します。あなたの説明を読み終えるまで、私は答えを受け入れることができませんでした:D
sandeepKumar

37

それは視覚化されるべきものよりもずっと退屈です。

文字通り「列挙可能」と呼ばれるすべてのプロパティに属性があります。falseに設定すると、for..inメソッドはそのプロパティをスキップし、存在しないふりをします。

「enumerable」がfalseに設定されているオブジェクトには、「valueOf」や「hasOwnProperty」などの多くのプロパティがあります。これは、JavaScriptエンジンがそれらを反復処理しないようにするためです。

Object.definePropertyメソッドを使用して、独自の列挙不可能なプロパティを作成できます。

  var car = {
    make: 'Honda',
    model: 'Civic',
    year: '2008',
    condition: 'bad',
    mileage: 36000
  };

  Object.defineProperty(car, 'mySecretAboutTheCar', {
    value: 'cat pee in back seat',
    enumerable: false
  });

車に秘密さえあるという事実は今や隠されている。もちろん、宿泊施設に直接アクセスして回答を得ることができます。

console.log(car.mySecretAboutTheCar); // prints 'cat pee in back seat'

ただし、プロパティが最初に存在することを知っておく必要があります。これは、プロパティを介してアクセスしようとした場合、for..inまたはObject.keys完全に秘密のままになるためです。

console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage']

彼らはそれを「forInAble」と呼んでいたはずです。


5
その最後の行に賛成-実際にforInAbleが呼び出されていたとしても、誰もそれについて質問することはないでしょう。これは私の質問現れます-なぜだろうあなた(または、なぜあなたがしなければならない)を列挙できないためにプロパティを設定されていますか?配列の長さプロパティは、列挙不可能なプロパティの例としてよく使用されますが、なぜそれを列挙可能に設定できなかったのですか(JavaScriptの制限ではなく、JavaScriptで列挙不可に設定されたのはなぜですか?そもそも)?
Chris

私の質問を明確にするために、以下が選択肢ではないと決定されたのはなぜですか:製造:ホンダモデル:市民の秘密:猫のおしっこ長さ:12
クリス

うーん...私自身の質問に対する答えを見つけたかもしれません。グーグル検索の「列挙型データとはどういう意味ですか?」列挙型データには、有限の値のセットがあります。列挙データ型は、その型に許可する値、または列挙値で構成されます。整数ベースの列挙型の場合、各列挙値は名前と基になる数値で構成されます。したがって、私が正しく理解している場合、可能な長さは無限にあるため、1つの名前に無限の名前を割り当てる必要があります。それぞれの長さに。あれは正しいですか?
Chris

さて、最初の質問に対処して、オブジェクトに列挙不可能なプロパティを設定するのは少しハックです。なぜなら、そのオブジェクトに何があったのかを見つけることができる唯一の方法は、コードを見て、コードベースとして見ることだからです。それが埋められる可能性があることを開発しています。だから、一般的には、それを使いたくないでしょう。文字列の文字数または配列の要素数を示す「.length」については、「for ... in」を使用している場合は含めたくないと思われるものです。Jsの神々が必然的にそうした理由に答えることはできません。彼らは私たちの理解を超えた理由(エヘン)意見を持っています。
Gabriel Kunkel

...そして私は、列挙されたデータ型に関する2番目の質問に答えることができないと思いますが、時間があれば、かなり長く噛み砕くことができるように見えます。:-)
ガブリエルクンケル

9

「列挙可能であるとはどういう意味ですか?」の視覚化が困難な場合 なぜあなた自身に尋ねないでください、それが無数であることは何を意味しますですか?

私はそれを少しこのように考えると、無数のプロパティが存在します、部分的に隠されています。数えられないものは奇妙なものであることを意味します。残っているものとして列挙可能であると想像できます- オブジェクトを発見して以来、私たちが遭遇するのに慣れている自然なプロパティです。検討する

var o = {};
o['foo'] =  0;                               // enumerable, normal
Object.defineProperty(o, 'bar', {value: 1}); // nonenumerable, weird

さて、疑似コードのfor..inように想像してみてください

for property in o:
    if not property enumerable continue // skip non-enumerable, "bar"
    else do /* whatever */              // act upon enumerable, "foo"

JavaScriptで入力したループの本体は、/* whatever */


8

ENUMERABLEの 1行の定義を記述します

Enumerableプロパティをfor / inループで返すことができるかどうかを指定します。

var obj = {};
Object.defineProperties(obj, {
    set1: {enumerable: true},
    set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]

0

メソッドは列挙できません。またはむしろ組み込みメソッドはそうではありません。列挙可能なもの は、Javaスクリプトにとって何を意味するかを検索した後です。それはプロパティ属性を参照するだけです。ecma3で作成されたすべてのオブジェクトは列挙可能で、ecma5 uはそれを定義できるようになりました...それだけです..:D lolは答えを見つけるのに少し時間がかかりました。しかし、それはデビッドフラナガンの本で話題になっていると思います。つまり、「非表示」または「非表示」ではなく、メソッドがfor inループに表示されないため、「非表示」になっていると思います。


0

enumデータ型を考えてください。異なる数に対応するオブジェクトの構造です。列挙可能として何かを宣言することは、それが特定の数に対応することを宣言することであり、オブジェクトのカウント可能なコンポーネントを表すディクショナリ内の場所を指定できるようにします。簡単に言えば、オブジェクトを列挙可能にすることは、コンパイラに「このプロパティは重要です。このオブジェクトのデータをチェックするときにこれを確認したい」と伝えるのと同じです。


0

オブジェクトが継承する組み込みメソッドは列挙可能ではありませんが、コードがオブジェクトに追加するプロパティは、明示的に指定されていない限り列挙可能です

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.