趣味でプログラミングやってる暇人の遊びですので、出来は全く保証できません。あしからず。
MDN web docsにあるデモってなに?
これ
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from
作る前の考察
上記の写真から分かる大まかな構造:
型判定し、型毎に分岐する関数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>
動かすと…?
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]
(https://wiki.developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects$history)
CC BY-SA 2.5 ライセンス
追記
デモを作りました。