javascriptで反復オブジェクトを列挙する方法
6214 ワード
for…in
for...inサイクルは、列挙可能な属性のみを巡回します.ArayおよびObjectのように、内蔵構造関数を用いて作成されたオブジェクトは、Object.prototypeおよびString.prototypeからエニュメレーションできない属性を継承します.例えば、StringのindexOf()方法またはObjectのtoString()方法です.オブジェクト自体のエニュメレート・プロパティーのすべてを巡回し、オブジェクトがその構造関数のプロトタイプから継承される属性(プロトタイプチェーンのオブジェクトに近い属性でプロトタイプの属性をカバーします).属性forを削除します.属性forを追加します.inサイクルは任意の順序でオブジェクトの属性を繰り返します.属性が1回の反復で変更された場合、後でアクセスされます.サイクル中の値は後の時間の値です.訪問前に削除された属性は後でアクセスされません.反復中にオブジェクトの属性に追加されます.その後の反復にアクセスすることも、無視されることもあります.
通常、反復中は、現在アクセス中の属性でない限り、オブジェクトに属性を追加、変更、または削除しない方が良い.ここでは、追加された属性が反復中に訪問されるかどうかは保証されていません.変更後の属性が変更前または修正後にアクセスされることは保証されていません.削除された属性が削除される前にアクセスされることは保証されていません.
配列反復とfor...inセクション
ヒント:for…inは、1つのArayを反復するために使用されるべきではなく、インデックス順序が重要である.
配列インデックスは整数名のエニュメレート・プロパティーだけで、共通のオブジェクト属性と同じです.for...inは、任意の特定の順序でインデックスに戻ります.for...inサイクルステートメントは、非整数タイプの名前と継承を含むすべてのエニュメレート・属性を返します.
反復の順序は実行環境に依存するので、配列遍歴は必ずしも順序で要素にアクセスするとは限らない.したがって、反復アクセス順序が重要な配列の場合は、整数インデックスでforループ(またはAray.prototype.forEach()またはfor...ofサイクルを使用することが望ましい.
独自のプロパティーセクションのみを繰り返す
オブジェクト自体の属性を考慮すれば、プロトタイプではなく、getOwnPropertyNames()またはhasOwnProperty()を使用して、ある属性がオブジェクト自体の属性であるかどうかを判定します.あるいは、外部コードの干渉がないことを知っているなら、検査方法を使って内蔵モデルを拡張してもいいです.
例
次の関数はパラメータとしてオブジェクトを受け入れます.呼び出し時にオブジェクトに入力されたすべてのエニュメレート・プロパティーを反復して、属性名とその対応する値の文字列を返します.
var obj={a:1,b:2,c:3}
for(var prop in obj){consolie.log(“obj.”+prop+“=”+obj[prop]);
//Output:/「Obj.a=1」/「Obj.b=2」/「Obj.c=3」以下の関数は、ハスOwnProperty()の使い方を説明しています.継承の属性は表示されません.
var triangle={a:1,b:2,c:3}
function ColoredTriangle(){this.co lor='red';
Colored Triangle.prototype=triangle;
var obj=new ColoredTriangle()
for(var prop in obj){if(obj.hasOwnProperty){
//Output:/「obj.co lor=red」
Object.keys()
オブジェクト自体の列挙可能な属性値を取得するために使用されますが、プロトタイプの属性は含まれていません.属性名からなる行列を返します.for.inのように属性がオブジェクトの元の順序で出力されることは保証されません.
//遍歴配列var colors=[red]、'green'、'blue';colors.length=10colors.push('yellow')Aray.prototype.demo=function()
Object.keys(colors)//[0]、「1」、「2」、「10」]
//遍歴対象function Person(name,age){this.name=name;this.age=age;
Person.prototype.demo=function(){}
var jnemy=new Person('jnemy',25);
Object.keys(jnemy)//[name]、「age」はES 5環境で、パラメータがオブジェクトではなく文字列に入ってきたら、TypeErrorに報告します.ES 6環境では、着信したのがオブジェクト以外のパラメータであれば、内部で強制的なオブジェクト変換が行われます.変換が成功しないとTypeErrが投げ出されます.
//ES 5環境でObject.keys('foo')//Type Error:「foo」is not an object
//ES 6環境でObject.keys('foo')//[「0」、「1」、「2」]
//nullに入るオブジェクトObject.keys(null)//Uncaght Type Error:Canot convert undefined or null to object
//undefinedObject.keysに入る;/Uncaght Type Error:Canot convert undefined or null to ObjectはObject.keys()はES 5上の方法ですので、ES 5以下の環境に対してpolyfillを行う必要があります.
//Fromhttps://developer.mozilla.org...if (!Object.keys){Object.keys=(function){
Object.getOwn PropertyNames()
Object.getOwnPropertyNames()メソッドは、指定されたオブジェクトのすべての自身の属性の属性名(エニュメレーションできない属性を含むが、名前の属性としてSymbol値を含まない)からなる行列を返します.
Object.getOwn PropertyNames()は、要素に対してObjj自身が持つ列挙または列挙できない属性名文字列である配列を返します.配列内の列挙属性の順序は、for...inサイクル(またはObject.keys)でオブジェクトの属性を反復するときと一致します.配列内の列挙できない属性の順序は定義されていません.var arr=[a],“b”,“c”;consolie.log(Object.getOwn PropertyNames(arr).sort()//[0]、「1」、「2」、「length」]
//クラス配列オブジェクトvar obj={0:“a”,1:“b”,2:“c”}consolie.log(Object.getOwn PropertyNames(Obj).sort()//[「0」、「1」、「2」]
//アラy.forEachを使用して属性名と属性値Object.getOwn PropertyNames(obj).forEach(function(val,idx,array){consolie.logs(val+「-」+obj[val])));出力/0->a/1->b/2->c
//エニュメレーション属性var my_Object.create({}、{get Foo:}.
consolie.log(Object.getOwn PropertyNames(myubbboj).sort()//[「foo」、「getFoo」は、エニュメレート・属性を取得すれば、Object.keysまたはfor…inサイクル(プロトタイプチェーン上のエニュメレート・属性も取得するが、hasOwnProperty()方法でフィルタリングすることができる.
以下の例は,この方法がプロトタイプチェーン上の属性を取得しないことを示している.
function PartentClass(){}PartClass.prototype.inheited Method=function(){}
function ChildClass(){this.prop=5;this.method=function()}.
ChildClass.prototype=new PartClass;ChildClass.prototype.prototypeMethod=function(){}
consolie.log(Object.getOwn PropertyNames)
var target=myObject;var enumand_nonenum=Object.getOwn PropertyNames;var enumonly=Object.keys;var nonenumonly=enum_and_nonenum.filter(function(key){
consolone.log(nonenum uonly);注:Aray.filter(filtufunc)法は、提供された関数によって実現されるテストのすべての要素を含む新しい配列を作成します.ヒントはES 5で、パラメータが元のオブジェクトタイプでない場合、TypeErr異常を投げます.ES 2015では、オブジェクト以外のパラメータを強制的にオブジェクトに変換します.
Object.getOwn PropertyNames('foo')//TypeError:「foo」is not an object(ES 5 code)
Object.getOwn PropertyNames('foo')//['length'、'0'、'1'、'2'』(ES 2015 code)
for...inサイクルは、列挙可能な属性のみを巡回します.ArayおよびObjectのように、内蔵構造関数を用いて作成されたオブジェクトは、Object.prototypeおよびString.prototypeからエニュメレーションできない属性を継承します.例えば、StringのindexOf()方法またはObjectのtoString()方法です.オブジェクト自体のエニュメレート・プロパティーのすべてを巡回し、オブジェクトがその構造関数のプロトタイプから継承される属性(プロトタイプチェーンのオブジェクトに近い属性でプロトタイプの属性をカバーします).属性forを削除します.属性forを追加します.inサイクルは任意の順序でオブジェクトの属性を繰り返します.属性が1回の反復で変更された場合、後でアクセスされます.サイクル中の値は後の時間の値です.訪問前に削除された属性は後でアクセスされません.反復中にオブジェクトの属性に追加されます.その後の反復にアクセスすることも、無視されることもあります.
通常、反復中は、現在アクセス中の属性でない限り、オブジェクトに属性を追加、変更、または削除しない方が良い.ここでは、追加された属性が反復中に訪問されるかどうかは保証されていません.変更後の属性が変更前または修正後にアクセスされることは保証されていません.削除された属性が削除される前にアクセスされることは保証されていません.
配列反復とfor...inセクション
ヒント:for…inは、1つのArayを反復するために使用されるべきではなく、インデックス順序が重要である.
配列インデックスは整数名のエニュメレート・プロパティーだけで、共通のオブジェクト属性と同じです.for...inは、任意の特定の順序でインデックスに戻ります.for...inサイクルステートメントは、非整数タイプの名前と継承を含むすべてのエニュメレート・属性を返します.
反復の順序は実行環境に依存するので、配列遍歴は必ずしも順序で要素にアクセスするとは限らない.したがって、反復アクセス順序が重要な配列の場合は、整数インデックスでforループ(またはAray.prototype.forEach()またはfor...ofサイクルを使用することが望ましい.
独自のプロパティーセクションのみを繰り返す
オブジェクト自体の属性を考慮すれば、プロトタイプではなく、getOwnPropertyNames()またはhasOwnProperty()を使用して、ある属性がオブジェクト自体の属性であるかどうかを判定します.あるいは、外部コードの干渉がないことを知っているなら、検査方法を使って内蔵モデルを拡張してもいいです.
例
次の関数はパラメータとしてオブジェクトを受け入れます.呼び出し時にオブジェクトに入力されたすべてのエニュメレート・プロパティーを反復して、属性名とその対応する値の文字列を返します.
var obj={a:1,b:2,c:3}
for(var prop in obj){consolie.log(“obj.”+prop+“=”+obj[prop]);
//Output:/「Obj.a=1」/「Obj.b=2」/「Obj.c=3」以下の関数は、ハスOwnProperty()の使い方を説明しています.継承の属性は表示されません.
var triangle={a:1,b:2,c:3}
function ColoredTriangle(){this.co lor='red';
Colored Triangle.prototype=triangle;
var obj=new ColoredTriangle()
for(var prop in obj){if(obj.hasOwnProperty){
console.log(`obj.${prop} = ${obj[prop]}`);
}//Output:/「obj.co lor=red」
Object.keys()
オブジェクト自体の列挙可能な属性値を取得するために使用されますが、プロトタイプの属性は含まれていません.属性名からなる行列を返します.for.inのように属性がオブジェクトの元の順序で出力されることは保証されません.
//遍歴配列var colors=[red]、'green'、'blue';colors.length=10colors.push('yellow')Aray.prototype.demo=function()
Object.keys(colors)//[0]、「1」、「2」、「10」]
//遍歴対象function Person(name,age){this.name=name;this.age=age;
Person.prototype.demo=function(){}
var jnemy=new Person('jnemy',25);
Object.keys(jnemy)//[name]、「age」はES 5環境で、パラメータがオブジェクトではなく文字列に入ってきたら、TypeErrorに報告します.ES 6環境では、着信したのがオブジェクト以外のパラメータであれば、内部で強制的なオブジェクト変換が行われます.変換が成功しないとTypeErrが投げ出されます.
//ES 5環境でObject.keys('foo')//Type Error:「foo」is not an object
//ES 6環境でObject.keys('foo')//[「0」、「1」、「2」]
//nullに入るオブジェクトObject.keys(null)//Uncaght Type Error:Canot convert undefined or null to object
//undefinedObject.keysに入る;/Uncaght Type Error:Canot convert undefined or null to ObjectはObject.keys()はES 5上の方法ですので、ES 5以下の環境に対してpolyfillを行う必要があります.
//Fromhttps://developer.mozilla.org...if (!Object.keys){Object.keys=(function){
'use strict';
var hasOwn = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwn.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwn.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
}
)(),}Object.getOwn PropertyNames()
Object.getOwnPropertyNames()メソッドは、指定されたオブジェクトのすべての自身の属性の属性名(エニュメレーションできない属性を含むが、名前の属性としてSymbol値を含まない)からなる行列を返します.
Object.getOwn PropertyNames()は、要素に対してObjj自身が持つ列挙または列挙できない属性名文字列である配列を返します.配列内の列挙属性の順序は、for...inサイクル(またはObject.keys)でオブジェクトの属性を反復するときと一致します.配列内の列挙できない属性の順序は定義されていません.var arr=[a],“b”,“c”;consolie.log(Object.getOwn PropertyNames(arr).sort()//[0]、「1」、「2」、「length」]
//クラス配列オブジェクトvar obj={0:“a”,1:“b”,2:“c”}consolie.log(Object.getOwn PropertyNames(Obj).sort()//[「0」、「1」、「2」]
//アラy.forEachを使用して属性名と属性値Object.getOwn PropertyNames(obj).forEach(function(val,idx,array){consolie.logs(val+「-」+obj[val])));出力/0->a/1->b/2->c
//エニュメレーション属性var my_Object.create({}、{get Foo:}.
value: function() { return this.foo; },
enumerable: false
}my_Obj.foo=1consolie.log(Object.getOwn PropertyNames(myubbboj).sort()//[「foo」、「getFoo」は、エニュメレート・属性を取得すれば、Object.keysまたはfor…inサイクル(プロトタイプチェーン上のエニュメレート・属性も取得するが、hasOwnProperty()方法でフィルタリングすることができる.
以下の例は,この方法がプロトタイプチェーン上の属性を取得しないことを示している.
function PartentClass(){}PartClass.prototype.inheited Method=function(){}
function ChildClass(){this.prop=5;this.method=function()}.
ChildClass.prototype=new PartClass;ChildClass.prototype.prototypeMethod=function(){}
consolie.log(Object.getOwn PropertyNames)
new ChildClass() // ["prop", "method"]
)[形エニュメレーションできない属性節を取得するだけの例としては、Aray.prototype.filter()を用いて、すべての属性名配列(Object.getOwn PropertyNames()法を用いて取得する)からエニュメレーション可能な属性を削除します.残りの属性はエニュメレーションできない属性です.var target=myObject;var enumand_nonenum=Object.getOwn PropertyNames;var enumonly=Object.keys;var nonenumonly=enum_and_nonenum.filter(function(key){
var indexInEnum = enum_only.indexOf(key);
if (indexInEnum == -1) {
// enum_only ,
// true
return true;
} else {
return false;
}
}consolone.log(nonenum uonly);注:Aray.filter(filtufunc)法は、提供された関数によって実現されるテストのすべての要素を含む新しい配列を作成します.ヒントはES 5で、パラメータが元のオブジェクトタイプでない場合、TypeErr異常を投げます.ES 2015では、オブジェクト以外のパラメータを強制的にオブジェクトに変換します.
Object.getOwn PropertyNames('foo')//TypeError:「foo」is not an object(ES 5 code)
Object.getOwn PropertyNames('foo')//['length'、'0'、'1'、'2'』(ES 2015 code)