location.hash から値を取り出してオブジェクト型で返す

Ajaxで使うかもしれない

let obj = hash2obj ("http://hoge.com#label?a=123&b=");

obj = {
    hash : '#label',
    id : 'label',
    value: { a: 123, b: undefined },
    query : '?a=123&b='
}
      function hash2obj (arg = window.location.hash) {
        const
          reg0 = /^(#([^\?\;\=]*)?)(\?.*)?/, //hash, id, paramater に切り分ける 
          reg1 = /\??([^\=\&\;\?]+)(?:=?([^\&\;$]*)?(?:\&|\;|$))/g; // name = value 
      
        if (arg = reg0.exec (arg)) {
          let [, hash, id, query] = arg, value = { };
          for (let r; r = reg1.exec (query); value[r[1]] = r[2]) ;
          return { id, hash, query, value };
        }
        else return null;
      }

オブジェクトからHTML要素を構成する

//obj = { tag:  '????', attr: { key: value, ... }, text: 'sample text', cildlen: [obj0, obj1, ... ]}

let arg = [
  {
    tag: 'ol', attr: { id: 'hoge', className: 'abc def', childlen: [
     //以下は同じ表示
      { tag: 'li', text: 'ABCDEFG' },
      { tag: 'li:ABCDEFG' },
      { tag: 'li', childlen: ['ABCDEFG']
    ]
  },
  {  tag: 'ol#hoge .abc .def' } //上の ol 要素と同じ意味
];
document.body.appendChild (makeElement (arg));

code:

function makeElement (arg, target = document.createDocumentFragment ()) {
  //tag: str -> tag #id .class : text に切り分ける
  const
    reg0 = /^\s*([a-z]+)\s*(?:#([a-z][0-9a-z]*))?\s*(\.[^\s\.]+(?:\s+\.[^\s\.]+)*)?\s*(?::?\s*(.*?)\s*)$/i,
    reg1 = /^\s+|\s{2,}|\s+$/g,//前後の空白、中間の2文字以上の空白を削除
    reg2 = /\./g;

  switch (Object.prototype.toString.call (arg).slice(8, -1)) {

  //引数の型で処理
  case 'Object' :
    let
      { tag = null, attr = { }, childlen = null, text = null } = arg,
      [ tagName, id, className, text1 ] = reg0.exec (tag),
      attr1 = { }, e;

    if (null == tagName)
      throw new Error ('tagName がありません');

    e = target.appendChild (document.createElement (tagName));//要素作成

    if (id) attr1.id = id;
    if (className) attr1.className = className.replace (reg1,'').replace (reg2,' ');

    Object.assign (e, attr, attr1);//属性上書き
    (text1 != null)&& ary2Element (text1, e);//文字列
    (text != null)&& ary2Element (text, e);//文字列
    (childlen)&& ary2Element (childlen, e); //子要素の追加
    break;
  
  case 'Array' :
    let fgm = document.createDocumentFragment ();
    arg.forEach (a=> ary2Element (a, fgm));
    target.appendChild (fgm);
    break;

  case 'undefined' : case 'Null' :
    arg = '';//break しない
  default :
    target.appendChild (document.createTextNode (String (arg)));
    break;
  }
  
  return target;
}

配列からテーブルを構成する

  //配列をテーブルに変換する(テキストの先頭を判別して th/td, colspan, rowspan, class を指定できる)
  function ary2TBody (ary, tbody = document.createElement ('tbody'), fg_del = false) {
    const
      //#[4,2].abc .def AAAA => <th colspan="4" rowspan="2" class="abc def">AAAA</th>
      reg0 = /^(#)?(?:\[(\d+)?(?:\,(\d+)?)?\])?\s*(\.[^\s\.]+(?:\s+\.[^\s\.]+)*)?\s*(.*?)$/,
      reg1 = /^\s+|\s{2,}|\s+$/g,//前後の空白、中間の2文字以上の空白を削除
      reg2 = /\./g;

    if (fg_del)
      [...tbody.childNodes].forEach (e=> e.remove ());//子要素の削除

    for (let row of ary) {
      let tr = tbody.appendChild (document.createElement ('tr')); //tbody.insertRow ();//fgmを許容するため
      for (let cell of row) {
        let
          str = null == cell ? '': String (cell);// null == undefined => true
        let  [, hash, colSpan = 1, rowSpan = 1, className = '', textContent ] = reg0.exec (str);
        let  td = tr.appendChild (document.createElement (hash ? 'th': 'td'));

        className = className.replace (reg1,'').replace (reg2,' ');//2つ以上のクラスに対応するため
        Object.assign (td, { colSpan, rowSpan, className, textContent});
      }
    }
    return tbody;
  }

配列からテーブルを作成する(単純高速版)

  //配列をテーブルに変換する(高速・フラグメントを tbody に指定できない)
  static ary2QTBody (ary = [ ], tbody = document.createElement ('tbody')) {
    for (let row of ary) {
      let tr = tbody.insertRow ();
      for (let cell of row) {
        tr.insertCell ().textContent = cell;
      }
    }
    return tbody;
    //return ary.reduce((a,b)=>(b.reduce((c,d)=>(c.insertCell().textContent=d,c),a.insertRow()),a),tbody);
  }