JavaScript console.log を書き換えて出力内容を横取りする。

# はじめに
console.log の機能を拡張したい場合、myconsoleLog とか作って、内部で console.log を読んだり、内容をファイルに出力したり、サーバーに情報送信、みたいなことはやるかもしれないですが、

ここでは console.log 自体を書き換えて機能追加します。

また、元の console.log に戻すこともできるようにします。

# コード

結構簡単です。

```js
  var consoleExt = {};
  consoleExt.originalConsoleLog = console.log;
  consoleExt.result = '';
  consoleExt.delimiter = ';';
  consoleExt.logOutput = true;

  consoleExt.log = function(message) {
    if (consoleExt.logOutput) {
      consoleExt.originalConsoleLog(message);
    }
    if (isObject(message)) {
      consoleExt.result += objToString(message) + consoleExt.delimiter;
    } else {
      consoleExt.result += message + consoleExt.delimiter;
    }
  };

  consoleExt.hook = function() {
    if (consoleExt.originalConsoleLog === console.log) {
      console.log = consoleExt.log;
    }
  };
  consoleExt.unhook = function() {
    if (consoleExt.originalConsoleLog !== console.log) {
      console.log = consoleExt.originalConsoleLog;
    }
  };
```

isObject は オブジェクト判定していて、objToStringは、オブジェクトを文字列にするものです。記事最後に全文載せています。

要点はそこではなく、単にconsole.logを書き換えているよ。ということです。

# 使い方

consoleExt.hook() で、console.log の横取りをします。
横取り後は、console.log をした時に、consoleExt.result に内容を追記していきます。

consoleExt.result をクリアしたりすることができます。

consoleExt.delimiter は、結果バッファに記録するときに console.logしたあとの区切り文字を指定します。

consoleExt.logOutput はBooleanで指定することができ、trueなら、新しい console.log を呼び出した時に、元の console.log で内容を出力します。

consoleExt.unhook() で、console.log の横取りを解除します。

# 全文

```html:index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title></title>

    <link rel="stylesheet" href="" >

    <script src=""></script>

<script>

  var isObject = function(value) {
    if (
      (Object.prototype.toString.call(value) === '[object Object]')
      && (!Array.isArray(value))
      && (value !== null)
      && (typeof value !== 'undefined')
    ) {
      return true;
    }
    return false;
  };

  //オブジェクトを文字列化する関数
  //JSON.stringify を利用して
  //  {valueA: 123, valueB: "123"}
  //という形式の文字列を作成する
  var objToString = function(obj) {
    var items = JSON.stringify(obj).split(',');
    items = items.map(function(element, index, array) {
      return element.replace(/(.+:)(.*)/,
        function(string, capture1, capture2) {
          return capture1.replace(/\"/g, '') + capture2;
        }).replace(/:/g, ': ');
      //[:]の前後でcapture1/2に分割して、
      //その後に[:]の前だけ["]を削除して
      //[:]は[: ]に置換
    });
    return items.join(', ');
    //[,]は[, ]に置換
  };

  var consoleExt = {};
  consoleExt.originalConsoleLog = console.log;
  consoleExt.result = '';
  consoleExt.delimiter = ';';
  consoleExt.logOutput = true;

  consoleExt.log = function(message) {
    if (consoleExt.logOutput) {
      consoleExt.originalConsoleLog(message);
    }
    if (isObject(message)) {
      consoleExt.result += objToString(message) + consoleExt.delimiter;
    } else {
      consoleExt.result += message + consoleExt.delimiter;
    }
  };

  consoleExt.hook = function() {
    if (consoleExt.originalConsoleLog === console.log) {
      console.log = consoleExt.log;
    }
  };
  consoleExt.unhook = function() {
    if (consoleExt.originalConsoleLog !== console.log) {
      console.log = consoleExt.originalConsoleLog;
    }
  };


consoleExt.hook();

consoleExt.result = '';
consoleExt.logOutput = true;
console.log('test01');

consoleExt.logOutput = false;
console.log('test02');

alert(consoleExt.result);

consoleExt.unhook();

console.log('test03');

alert(consoleExt.result);

</script>
  </head>
  <body>
  </body>
</html>
```

実行すると、
test01 は、コンソールの出力され、結果バッファに記録され、

test02 は、コンソールに出力されないが、結果バッファに記録され、

test03 は、コンソールに出力されるが、結果バッファには記録されない、

というように動作コントロールできます。