【JavaScript】class構文で宣言したクラスのメソッド名を取得する

結論としては、prototypeに対して Object.getOwnPropertyNames()を使えばよい。

class Person {
  sayHello () {
    console.log('hello')
  }
}

let methods = Object.getOwnPropertyNames(Person.prototype)
console.log(methods)
// > [ 'constructor', 'sayHello' ]

Object.keys()で取ろうとしてハマった

ES2015 の class 構文が、 prototypeチェーンで定義する従来のクラス宣言と違って、Object.keys()でメソッドを取得できなかった。

// 従来のクラス宣言
function Person () {}

Person.prototype.sayHello = function () {
  console.log('hello')
}

let methods = Object.keys(Person.prototype)
console.log(methods)
// > [ 'sayHello' ]
// class は糖衣構文だから同じようにできるよね
class Person {
  sayHello () {
    console.log('hello')
  }
}

let methods = Object.keys(Person.prototype)
console.log(methods)
// > []
// えっ、空!??

混乱した。

console.log('sayHello' in Person)
// > true

メソッドは存在しているが、Object.keys()では取ってこれない。

原因と対策

class 構文で宣言したメソッドは、列挙不可能なプロパティになる。

// 列挙可能性の確認
class Person {
  // ES2015方式
  sayHello () {
    console.log('hello')
  }
}

// 従来の方式
Person.prototype.sayGoobye = function () {
  console.log('Good bye')
}

console.log(Person.prototype.propertyIsEnumerable('sayHello'))
// > false
console.log(Person.prototype.propertyIsEnumerable('sayGoobye'))
// > true
// なるほど

なので、列挙不可能なプロパティ名を取ってくるには、Object.getOwnPropertyNames()を使うというわけ。