Question: I am writing some code to extend `Object`, and I would like to loop over the methods within the object. When I output the value of `this.constructor`, I see the methods that I would like (in the example below I see `test`). However, when I loop over the methods using a for, it only displays the method `getType`. How can I get just the methods of `class A`?

```js
Object.prototype.getType = function () {
  // Outputs correct class and methods
  console.log(this.constructor)

  for (let i in this.constructor) {
    // Outputs wrong methods
    console.log(i)
  }
}

class A {
  test() {console.log('hello')}
}

new A().getType()
```

Answer: 
Two problems:

1. Properties can be enumerable – visited by for…in loops – or not. When you define a method in a `class`, the default is non-enumerable. (`Object.prototype.getType`, on the other hand, is enumerable because that’s the default when you create a property by assignment.)
2. You’re looping over properties of what the object claims is its constructor, but non-static methods like `test` are properties of the constructor’s `prototype` property (`A.prototype`), not the constructor itself (`A.test` isn’t a thing).

You can find non-enumerable properties with the [`Object.getOwnPropertyNames`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames) function:

```
Object.prototype.getType = function () {
  for (let name of Object.getOwnPropertyNames(this.constructor.prototype)) {
    console.log(name)
  }
}

```

Note that this only includes *own properties* – properties directly on the object – so if you want to include inherited methods, you’ll have to go up the prototype chain.

```
function* getAllPropertyNames(obj) {
  do {
    yield* Object.getOwnPropertyNames(obj)
  } while (obj = Object.getPrototypeOf(obj))
}

Object.prototype.getType = function () {
  for (let name of getAllPropertyNames(this.constructor.prototype)) {
    console.log(name)
  }
}

```

And if you want to include properties directly on the object, you’ll have to start there (and hope `this.constructor.prototype` is `Object.getPrototypeOf(this)`).

```
Object.prototype.getType = function () {
  for (let name of getAllPropertyNames(this)) {
    console.log(name)
  }
}

```

Also, don’t extend `Object.prototype`. *Especially* not with enumerable properties. Management is not responsible for dependencies that break in mysterious ways when you do this.
The *getType* name seems inappropriate, what you're looking for are properties, so *getAllProperties* seems a better name.

As others have said, you need to go up the `[[Prototype]]` chain for a number of reasons:

1. Objects inherit from their constructor's prototype, not the constructor itself
2. The *constructor* property may not point to the actual constructor
3. The *constructor.prototype* may not be the one used to create the object
4. There may be multiple constructors
5. Inherited properties may be duplicated, you need to get just the "closest" one

The `[[Prototype]]` chain ends in *null*, which is the prototype for Object.prototype and is the top of all prototype hierarchies. The function should also remove duplicates, which can occur on each prototype (e.g. *constructor*, and *length* is pretty common).

```js
function getAllProperties(obj) {
  // Recursively get properties up [[Prototype]] chain
  function loop(obj) {
    let props = Object.getOwnPropertyNames(obj);
    let proto = Object.getPrototypeOf(obj);

    // Stop at null
    if (proto !== null) {
      return props.concat(loop(proto));
    }
    return props;
  }

  let allProps = loop(obj);

  // Remove duplicates
  return allProps.filter((prop, i) => !allProps.includes(prop, i+1));
}

console.log(getAllProperties('a'))
```

If you want just methods, then filter as you go for `typeof x == 'function'`:

```js
function getAllMethods(obj) {
  // Recursively get properties up [[Prototype]] chain
  function loop(obj) {
    // Get all properties, filter for functions
    let props = Object.getOwnPropertyNames(obj).filter((prop, i, props) => typeof props[prop] == 'function');
    let proto = Object.getPrototypeOf(obj);

    // Stop at null
    if (proto !== null) {
      return props.concat(loop(proto));
    }
    return props;
  }

  let allMethods = loop(obj);

  // Remove duplicates
  return allMethods.filter((prop, i) => !allMethods.includes(prop, i + 1));
}

console.log(getAllMethods('a'))
```