javascript の Object のメソッドにおける列挙可能とか直接所有とかの扱い

javascriptのObjectのプロパティにはいろんな種類がある。
`[[Enumerable]]`(列挙可能性)みたいな属性がついていたり、「直接所有(own)」か「継承したもの」かの違いだったり、キーが`String`だったり`Symbol`だったりとかする。
キーや値を取得したり色々するメソッドはいくつかありそれらについての扱いが異なる。
`hasOwnProperty`とか`assign`とか`entries`とかそんなのでどのように扱われているかしらべた。
目的は継承もふくめて取得すること。
#実行したコード

```js
var syms={
	// Symbol の一覧
	'   Own    Enumerable Symbol':Symbol('   Own    Enumerable Symbol'),
	'   Own nonEnumerable Symbol':Symbol('   Own nonEnumerable Symbol'),
	'nonOwn    Enumerable Symbol':Symbol('nonOwn    Enumerable Symbol'),
	'nonOwn nonEnumerable Symbol':Symbol('nonOwn nonEnumerable Symbol'),
};
// own:直接所有 enumerable:列挙可能性
function C(){
	// 直接所有のプロパティを設定
	Object.defineProperty(this   ,     '   Own    Enumerable String' ,{value: 11,enumerable: true});
	Object.defineProperty(this   ,     '   Own nonEnumerable String' ,{value: 22,enumerable:false});
	Object.defineProperty(this   ,syms['   Own    Enumerable Symbol'],{value: 44,enumerable: true});
	Object.defineProperty(this   ,syms['   Own nonEnumerable Symbol'],{value: 55,enumerable:false});
	return this;
}
// プロトタイプを設定
Object.defineProperty(C.prototype,     'nonOwn    Enumerable String' ,{value:123,enumerable: true});
Object.defineProperty(C.prototype,     'nonOwn nonEnumerable String' ,{value:345,enumerable:false});
Object.defineProperty(C.prototype,syms['nonOwn    Enumerable Symbol'],{value:678,enumerable: true});
Object.defineProperty(C.prototype,syms['nonOwn nonEnumerable Symbol'],{value:890,enumerable:false});
// オブジェクト生成   上で定義した 直接所有/継承 列挙可能/不可能 String/Symbol それぞれのプロパティを持つ
var obj=new C();
// 以下調べるための実行
console.log('entries              :',Object.entries              (obj));
console.log('getOwnPropertyNames  :',Object.getOwnPropertyNames  (obj));
console.log('getOwnPropertySymbols:',Object.getOwnPropertySymbols(obj));
console.log('keys                 :',Object.keys                 (obj));
console.log('values               :',Object.values               (obj));
var keys=[];
for(let key in obj)keys.push(key);
console.log('for ... in           :',keys);
console.log('getOwnPropertyDescriptors:',Object.getOwnPropertyDescriptors(obj));
console.log('assign:',Object.assign(Object.create(null),obj));
console.log('hasOwnProperty       :    Own    Enumerable String',obj.hasOwnProperty      (     '   Own    Enumerable String' ));
console.log('hasOwnProperty       :    Own nonEnumerable String',obj.hasOwnProperty      (     '   Own nonEnumerable String' ));
console.log('hasOwnProperty       : nonOwn    Enumerable String',obj.hasOwnProperty      (     'nonOwn    Enumerable String' ));
console.log('hasOwnProperty       : nonOwn nonEnumerable String',obj.hasOwnProperty      (     'nonOwn nonEnumerable String' ));
console.log('hasOwnProperty       :    Own    Enumerable Symbol',obj.hasOwnProperty      (syms['   Own    Enumerable Symbol']));
console.log('hasOwnProperty       :    Own nonEnumerable Symbol',obj.hasOwnProperty      (syms['   Own nonEnumerable Symbol']));
console.log('hasOwnProperty       : nonOwn    Enumerable Symbol',obj.hasOwnProperty      (syms['nonOwn    Enumerable Symbol']));
console.log('hasOwnProperty       : nonOwn nonEnumerable Symbol',obj.hasOwnProperty      (syms['nonOwn nonEnumerable Symbol']));
console.log('propertyIsEnumerable :    Own    Enumerable String',obj.propertyIsEnumerable(     '   Own    Enumerable String' ));
console.log('propertyIsEnumerable :    Own nonEnumerable String',obj.propertyIsEnumerable(     '   Own nonEnumerable String' ));
console.log('propertyIsEnumerable : nonOwn    Enumerable String',obj.propertyIsEnumerable(     'nonOwn    Enumerable String' ));
console.log('propertyIsEnumerable : nonOwn nonEnumerable String',obj.propertyIsEnumerable(     'nonOwn nonEnumerable String' ));
console.log('propertyIsEnumerable :    Own    Enumerable Symbol',obj.propertyIsEnumerable(syms['   Own    Enumerable Symbol']));
console.log('propertyIsEnumerable :    Own nonEnumerable Symbol',obj.propertyIsEnumerable(syms['   Own nonEnumerable Symbol']));
console.log('propertyIsEnumerable : nonOwn    Enumerable Symbol',obj.propertyIsEnumerable(syms['nonOwn    Enumerable Symbol']));
console.log('propertyIsEnumerable : nonOwn nonEnumerable Symbol',obj.propertyIsEnumerable(syms['nonOwn nonEnumerable Symbol']));
```

#出力
多少見やすいように成型
GoogleChromeとFirefoxで差はなし。

```js

entries              : [Array(2)]
	0: (2) ["   Own    Enumerable String", 11]
getOwnPropertyNames  : (2) ["   Own    Enumerable String", "   Own nonEnumerable String"]
getOwnPropertySymbols: (2) [Symbol(   Own    Enumerable Symbol), Symbol(   Own nonEnumerable Symbol)]
keys                 : ["   Own    Enumerable String"]
values               : [11]
for ... in           : (2) ["   Own    Enumerable String", "nonOwn    Enumerable String"]
getOwnPropertyDescriptors: {...}
	      "   Own    Enumerable String": {value: 11, writable: false, enumerable:  true, configurable: false}
	      "   Own nonEnumerable String": {value: 22, writable: false, enumerable: false, configurable: false}
	Symbol(   Own    Enumerable Symbol): {value: 44, writable: false, enumerable:  true, configurable: false}
	Symbol(   Own nonEnumerable Symbol): {value: 55, writable: false, enumerable: false, configurable: false}
assign: {...}
	      "   Own    Enumerable String": 11
	Symbol(   Own    Enumerable Symbol): 44
hasOwnProperty       :    Own    Enumerable String true
hasOwnProperty       :    Own nonEnumerable String true
hasOwnProperty       : nonOwn    Enumerable String false
hasOwnProperty       : nonOwn nonEnumerable String false
hasOwnProperty       :    Own    Enumerable Symbol true
hasOwnProperty       :    Own nonEnumerable Symbol true
hasOwnProperty       : nonOwn    Enumerable Symbol false
hasOwnProperty       : nonOwn nonEnumerable Symbol false
propertyIsEnumerable :    Own    Enumerable String true
propertyIsEnumerable :    Own nonEnumerable String false
propertyIsEnumerable : nonOwn    Enumerable String false
propertyIsEnumerable : nonOwn nonEnumerable String false
propertyIsEnumerable :    Own    Enumerable Symbol true
propertyIsEnumerable :    Own nonEnumerable Symbol false
propertyIsEnumerable : nonOwn    Enumerable Symbol false
propertyIsEnumerable : nonOwn nonEnumerable Symbol false
```

#結果
|                         |enumerable|    own   |String/Symbol|動作	|列挙可/不可能性	|直接所有/継承	|
|:------------------------|:--------:|:--------:|:-----------:|:------:	|:------------:	|:------------:	|
|entries                  |true      |true      |String       |取得	|可能のみ	|直接所有のみ	|
|getOwnPropertyNames      |true/false|true      |String       |取得	|両方		|直接所有のみ	|
|getOwnPropertySymbols    |true/false|true      |       Symbol|取得	|両方		|直接所有のみ	|
|keys                     |true      |true      |String       |取得	|可能のみ	|直接所有のみ	|
|values                   |true      |true      |String       |取得	|可能のみ	|直接所有のみ	|
|for ... in               |true      |true/false|String       |取得	|可能のみ	|両方		|
|getOwnPropertyDescriptors|true/false|true      |String/Symbol|取得	|両方		|直接所有のみ	|
|assign                   |true      |true      |String/Symbol|代入	|可能のみ	|直接所有のみ	|
|hasOwnProperty           |true/false|true      |String/Symbol|検査	|両方		|直接所有のみ	|
|propertyIsEnumerable     |true      |true      |String/Symbol|検査	|可能のみ	|直接所有のみ	|

#結論
直接所有/継承の両方を取得するには`for ... in`を使うことになりそう。
ただし`Symbol`が含まれないのでそれを含めようと思ったら面倒くさいことになりそう。
列挙可/不可能性,直接所有/継承,String/Symbolをそれぞれ指定できるやつがあればいいんだけど。
コードが冗長なのは気にしない。