필요 지식
#javascript

Front-end 의 Javascript 개발을 할때 가장 많이 사용하는 함수는 아마도 console.log() 일 것입니다. 설사 angular 나 react,vue.js 를 기반으로 개발을 하더라도 console.log() 함수는 여러가지 상황에서 다용도로 사용하게 되는 필수템 일것입니다.

그러나 브라우저의 개발자 도구에 고스란히 남는다는 문제 때문에 개발할때는 사용하고 운영 배포시엔 소스에서 삭제하고 올리는 경우도 있는것 같습니다. 매우 번거롭죠.

공통 함수를 하나 만들어서 모든 개발자에게 그 함수만 사용하라고 가이드 할 수 있을것 같습니다. 그럼 공통 프레임워크에서 공통함수의 기능을 제어하면 되겠죠. 아래처럼요.

  1. var obj = {
  2. name : '객체',
  3. val : 103,
  4. abc : function() {
  5. }
  6. };
  7. function logger(val) {
  8. console.log(val);
  9. }
  10. logger(obj);

물론 위의 코드는 정상적으로 실행되지만 치명적인 단점이 있습니다.
첫째로 기존에 사용한 console.log() 를 logger() 형태로 일일이 바꿔줘야 한다는 것이고 두번째는 logger()가 손에 익을때까지 누군가는 계속 console.log()를 사용할 것이란 겁니다. 그리고 세번째 단점은 실제로 웹페이지에 적용해본 후 로그 결과를 살펴보겠습니다.

출력결과

위 출력에서 하나는 새로 만든 logger() 함수를 통해 출력한 것이고 다른 하나는 console.log() 함수를 호출한 것입니다. 어떤것일까요? 우측에 보이는 파일명:소스라인 을 클릭하면 소스 위치를 추적할 수 있습니다.

소스위치

소싀 659번째와 663번째 줄 둘다 console.log() 함수를 사용한 위치라는 것을 보실수 있습니다. 정상인거 아니냐구요? 만약 아래와 같이 로그를 찍었다면 아웃풋에서 알고 싶은 소스의 위치는 어디 일까요?

  1. var state = 1;
  2. ...
  3. logger(state);
  4. ...
  5. logger(state);
  6. ...
  7. logger(state);

물론 logger() 함수를 사용한 곳의 위치를 알고 싶을겁니다. 그러나 위에서 만든 로거는 console.log()를 사용한 곳, 즉 logger() 함수가 정의된 곳의 위치만 나타낼 뿐입니다.

이러한 기능을 염두해두고 지금부터 console wrapper 두 가지 방법을 보이겠습니다.

ver1. function clone

  1. function newConsole() {
  2. var orgConsole = console;
  3. this.mlist = {};
  4. for(var m in orgConsole) {
  5. if (typeof orgConsole[m] == 'function')
  6. this.mlist[m] = orgConsole[m].bind(orgConsole)
  7. }
  8. this.mlist.off = function() {
  9. this.log = function() {};
  10. };
  11. this.mlist.on = function() {
  12. this.log = orgConsole.log;
  13. };
  14. return this.mlist;
  15. }
  16. console = new newConsole();

이 방식은 console객체의 함수 전체를 복제한 객체에 on/off 함수를 추가하는 방법입니다. 함수의 일부만 복제한다면 기능을 제한할 수도 있겠죠. 그러나 node.js에는 적용 불가능하고 브라우저 기반의 Front-end 스크립트에만 적용 가능합니다.

ver2. property 추가

  1. var orgConsole = console;
  2. var orgLog = console.log;
  3. console.off = function() {
  4. this.log = function() {};
  5. };
  6. console.on = function() {
  7. this.log = orgLog;
  8. };

첫번째 방법과는 달리 기존의 console 객체를 재정의하지 않고 속성만 추가하는 형태입니다. 단 속성으로 추가된 함수가 호출되면 console.log()를 원래 함수 또는 빈함수로 교체할 뿐이죠. 두번째 방법은 node.js에서도 적용이 가능하며 가장 간단한 방법으로 완벽하게 동작합니다.

정리

어떤 방식을 이용하던지 각 상황에 맞게 응용할 수 있을것 같습니다. 예를들어 글로벌 변수에 개발서버,운영서버 구분값을 추가하고 그 구분값에 따라 console.log 를 on/off 시킨다면 개발자는 로그를 얼마든지 자유롭게 사용할 수 있겠죠. 혹시 Front-end 로그로 스트레스 받고 있다면 바로 적용해보세요.

최종 샘플

  1. (function (type) {
  2. var orgConsole = console;
  3. if(type == 1) {
  4. //1번
  5. function newConsole() {
  6. this.mlist = {};
  7. for(var m in orgConsole) {
  8. if (typeof orgConsole[m] == 'function')
  9. this.mlist[m] = orgConsole[m].bind(orgConsole)
  10. }
  11. this.mlist.off = function() {
  12. this.log = function() {};
  13. };
  14. this.mlist.on = function() {
  15. this.log = orgConsole.log;
  16. };
  17. return this.mlist;
  18. }
  19. console = new newConsole();
  20. }
  21. else if(type == 2) {
  22. // 2번
  23. var orgLog = console.log;
  24. console.off = function() {
  25. this.log = function() {};
  26. };
  27. console.on = function() {
  28. this.log = orgLog;
  29. };
  30. }
  31. })(2); //1 과 2에 따라 로그 방식이 바뀜
  32. var obj = {
  33. name : '객체',
  34. val : 103,
  35. abc : function() {
  36. }
  37. };
  38. console.log('hello'); //hello 로그 출력
  39. console.off(); //로그 끄기
  40. console.log('show me'); //출력되지 않음
  41. console.on(); //로그 켜기
  42. console.log(obj); //obj 로그 출력
  43. console.log('say hello'); //say hello 로그 출력