for...in
列挙可能プロパティに対して順不同で反復処理を実行する。
- ※順不同:基本的には順番通りに出力されるが、それが担保されているわけではない。
- プロトタイプチェーン内も列挙対象となる。
- プロトタイプチェーンのみ列挙したい場合は
Object.hasOwnProperty()
を使う。
- プロトタイプチェーンのみ列挙したい場合は
- Symbolはfor..inでは列挙対象にならない。
case1
- オブジェクトをinで回す場合はkeyが戻り値になる。
- valueを取得する場合はobjに対して[key]を渡す形なる。
const obj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
}
for(let key in obj){
console.log(key, obj[key]);
}
case2
- prototypeにメソッドを追加していた場合にメソッドを列挙対象外にしたい場合。
- definePropertyのディスクリプターのenumerableをfalseにすることで列挙対象外となる。
- そもそもビルトインメソッドが列挙対象外になっているのは、enumerable: falseという設定になっているから。
const obj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
}
Object.prototype.method = function(){}
Object.defineProperty(Object.prototype, 'method',{
enumerable: false
})
//ディスクリプターの設定確認
const d = Object.getOwnPropertyDescriptor(Object.prototype, 'method')
console.log(d)
// {writable: true, enumerable: false, configurable: true, value: ƒ}
//ビルドインメソッドの enumerable: falseになっているかどうかの確認。
const c = Object.getOwnPropertyDescriptor(Object.prototype, 'hasOwnProperty')
console.log(c)
//{writable: true, enumerable: false, configurable: true, value: ƒ}
for(let key in obj){
console.log(key, obj[key]);
}
case3
- case2の応用として、objオブジェクトの一部だけdefinePropertyで列挙外にすることができる。
const obj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
}
Object.defineProperty(obj, 'prop1',{
enumerable: false
})
for(let key in obj){
console.log(key, obj[key]);
}
case4
- for...inのなかでprototypeを列挙から外し合い場合はhasOwnProtertyを使うと良い。
- hasOwnProperty() メソッドは、オブジェクト自身が(継承されていない)指定されたプロパティを持っているかどうかを示す真偽値を返します。
const obj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3'
}
for(let key in obj){
//objが自身のプロパティかどうかを真偽値で評価している。
//prototypeに格納されているものは全て継承されたものなのでfalseになり、列挙対象外となる;。
if(obj.hasOwnProperty(key)){
console.log(key, obj[key]);
}
}
case5
- Symbolが列挙外になっているかの確認
- 変数をオブジェクトに格納する場合はkeyに
[変数]:value
となる。
const s = Symbol();
const obj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3',
[s]: 'value4'
}
const e = Object.getOwnPropertyDescriptor(obj, s)
console.log(s)
>>> Symbol()
//Symbolとして評価されている。
for(let key in obj){
console.log(key, obj[key]);
}
>>> prop1 value1
>>> prop2 value2
>>> prop3 value3
//Symbolは表示されなかった。