LoginSignup
0

More than 5 years have passed since last update.

jsのクラス要素解析

Last updated at Posted at 2018-04-05

はじめに

jsのclassに関して以下の情報を得たい
- getterの有無とその関数
- setterの有無とその関数
- methodの関数
- static methohd の関数
- class の宣言時の名前
- constructor の引数名

主に以下の関数を用いることで解析できます.
- Reflect.getOwnPropertyDescriptor
- Reflect.ownKeys
- Function.toString()

コード

クラス雛形用意

class Piyo {
  constructor(argA, argB) {
    console.log('@constructor :: ', Reflect.ownKeys(this));
    this.memberA = argA;
  }
  get getA() {
    console.log('@getA :: ', Reflect.ownKeys(this));
  }
  set setA(value) {
    console.log('@setA :: ', Reflect.ownKeys(this));
  }
  static staticA() {
    console.log('@staticA :: ', Reflect.ownKeys(this));
  }
  methodA() {
    console.log('@methodA :: ', Reflect.ownKeys(this));
  }
}
function listupTest(Hoge) {
  let hoge = new Hoge('ARG_A', 'ARG_B');
  // members: [ 'memberA' ]
  console.log('members:', Reflect.ownKeys(hoge));
  // methods: [ 'constructor', 'getA', 'setA', 'methodA' ]
  console.log('methods:', Reflect.ownKeys(Hoge.prototype));
  // statics: [ 'length', 'prototype', 'staticA', 'name' ]
  console.log('statics:', Reflect.ownKeys(Hoge));
  // name is: Piyo
  console.log('name is:', Hoge.name);
  let reflectHoge = k => Reflect.getOwnPropertyDescriptor(Hoge.prototype, k);
  let res = {};
  res.memberA = hoge.memberA;
  res.methodA = reflectHoge('methodA').value;
  res.getA = reflectHoge('getA').get;
  res.setA = reflectHoge('setA').set;
  res.staticA = Hoge.staticA;
  res.props = getParams(Hoge, true);
  // @methodA ::  [ 'memberA', 'methodA', 'getA', 'setA', 'staticA', 'props' ]
  res.methodA();
  // @getA ::  [ 'memberA', 'methodA', 'getA', 'setA', 'staticA', 'props' ]
  res.getA();
  // @setA ::  [ 'memberA', 'methodA', 'getA', 'setA', 'staticA', 'props' ]
  res.setA();
  // @staticA ::  [ 'memberA', 'methodA', 'getA', 'setA', 'staticA', 'props' ]
  res.staticA();
  // [ 'argA', 'argB' ]
  console.log(res.props);
}
listupTest(Piyo);

参考

getParams は以下を参考にしました.(constructor系functionに未対応だったのでそこの処理は追加しました)
https://qiita.com/chick307/items/1902fb32d252310d516d

function getParams(func, isConstructor = false) {
  // コメントと空白を取り除いて正規化
  let source = func.toString().replace(/\/\/.*$|\/\*[\s\S]*?\*\/|\s/gm, '');
  if (!isConstructor) {
    // 最初の丸かっこのもの
    let params = source.match(/\((.*?)\)/)[1].split(',');
    if (params.length === 1 && params[0] === '') return [];
    return params;
  }
  let firstName = source.replace(/^.*?\{/, "").replace(/\(.*$/, "");
  // constructor 系
  if (firstName === "constructor") return getParams(func, false);
  // babel系
  if (firstName === "_classCallCheck") return getParams(func, false);
  console.assert(false, "declare consturctor first!!");
}

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