3
1

More than 3 years have passed since last update.

MDN web docsにあるデモと同じように、console.logの中身を掠め取って綺麗に表示するものを作りたい。

Last updated at Posted at 2020-03-13

趣味でプログラミングやってる暇人の遊びですので、出来は全く保証できません。あしからず。

MDN web docsにあるデモってなに?

これ

egsrhtjuiotjyku.png
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from

作る前の考察

dsgfdhfgj.png

上記の写真から分かる大まかな構造:

型判定し、型毎に分岐する関数a
Boolean、Null、Undefined、Number、String等:
    ┗String()で文字化
Array:
    ┗Arrayを解析する関数bを呼び出し
        (中身に応じてaを再帰的に呼び出し)
Objectやその他:
    ┗Objectを解析する関数cを呼び出し
        (中身に応じてaを再帰的に呼び出し)

console.logの引数を横流しする仕組み

この順番に書いていきます。

型判定する関数a

function a(x) {
    var t = typeof x;
    if(t == "boolean" || x == null || x == undefined || t == "number" || t == "symbol") {
       return String(x);
    }
    else if(t == "bigint") {
       return String(x) + "n";
    }
    else if(t == "string") {
       return "\"" + String(x) + "\"";
    }
    else if(Object.prototype.toString.call(x) === "[object Array]") {
       return "Array " + b(x);//配列を解析する関数
    }
    else {
       return c(x);//オブジェクトを解析する関数
    }
}

配列を解析する関数b

function b(x) {
    var ary = [];
    for(var y of x) {
        ary.push(a(y));//再帰的にaを呼び出し
    }
    var r = "[" + ary.join(", ") + "]";
    return r;
}

オブジェクトなどの残りを解析する関数c

オブジェクトは種類がいっぱいあり、辞書型なオブジェクトとそうでないものを分ける必要がある。安易に文字形式にできないワケワカメなオブジェクトもあるので、それらは型名だけ吐かせる。Object.prototype.constructor.nameでゴリゴリ種類を判別する。

function c(x) {
    var n = x.constructor.name;
    var r = "";

    /*オブジェクト*/
    if(n == "Object") {
        var ary = [];
        for(var k in x) {
            ary.push(k + ": " + a(x[k]));//再帰的にaを呼び出し
        }
        r = "Object {" + ary.join(", ") + "}";
    }
    /*構造化データ*/
    else if(n == "ArrayBuffer" || n == "SharedArrayBuffer" || n == "DataView") {
        r += n + "(" + x.byteLength + ") {}";
    }
    /*索引付きコレクション*/
    else if(n.match(/^.*?Array$/)) {
        r += n + "(" + x.length + ") " + b(x);//配列と同じようなものなので、配列解析に任せてしまいます
    }
    /*Promise(どうあがいても中身を取り出せなかったので、中身は無かったことに…。)*/
    else if(n == "Promise") {
        r += n + " {}";
    }
    /*(本当は他にも例外処理をしないといけないものがある気がするものの、*/
    /* オブジェクトの種類が膨大なので、この辺りで諦めました。)*/
    /*残りを文字化*/
    else {
        r += String(x);
    }
    return r;
}

console.logの引数を横流しして完成

/*改変前に退避*/
var _l = console.log;

console.log = function() {
    var t = [];
    for(var arg of arguments) {
        var o = a(arg);//型判定関数に引数を受け渡し
        t.push(o);
    }
    var c = t.join(" ");//結果
    document.getElementById("result").innerHTML += "\n> " + c + "\n";
    _l.apply(console, arguments);
}
<pre id="result"></pre>

動かすと…?

JavaScript
console.log(0);
console.log("0");
console.log([0, 1, function() {}]);
console.log({a: void 0});
console.log({a: {a: [0, 1, 2]}});
console.log(new RegExp("^a", "ig"));
console.log(new Int16Array(2));
console.log(new ArrayBuffer(2));

とすると、

> 0

> "0"

> Array [0, 1, function() {}]

> Object {a: undefined}

> Object {a: Object {a: Array [0, 1, 2]}}

> /^a/gi

> Int16Array(2) [0, 0]

> ArrayBuffer(2) {}

となる。


参考文献

標準ビルトインオブジェクト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects
by MDN contributors
CC BY-SA 2.5 ライセンス


追記

デモを作りました。

http://topia.wdfiles.com/local--code/console/2

3
1
0

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
3
1