0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【javascript】for...in と列挙可能性

Posted at

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は表示されなかった。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?