重写并自定义console.log()输出样式

news2024/11/16 18:00:34

0. 背景

笔者在开发的实践过程中对于控制台内容的输出情况有一些特殊的需求,然而,普通的console.log()函数不能提供很好的支持,因此需要探索一些自定义的实现方式,以便满足开发需求,一些开发需求如下:

  1. 输出内容统一管理,调整开启或关闭;
  2. 不同的开发阶段显示不同的输出样式,如:测试、调试、生产;
  3. 统一样式调整;
  4. ……

1. 实现

1.1 简单重写:使用变量保存console.log

let fun = console.log
console.log = function () {
	fun(...arguments)
}

1.2 简单重写:使用立即执行函数

console.log = (function (oriLogFunc) {
	return function () {
		oriLogFunc('debug : ', ...arguments)
	}
})(console.log)

1.3 自定义封装

export default {
  // 输出等级: 0-no, 1-error, 2-warning, 3-info, 4-debug, 5-log
  level: 5,
  // 输出模式: 0-default, 1-normal, 2-random
  mode: 1,
  // 是否输出图标
  hasIcon: false,
  // 是否打印函数名和所在文件行号
  isPrintLine: true,
  // 图标
  icons: ['🌵', '🎍', '🐾', '🌀', '🐚', '🥝', '🥜', '🥕', '🥒', '🌽', '🍒', '🍅', '🍑', '🍋', '🍈', '🌶', '🌰', '🍠', '🍆', '🍄', '🍐', '🍌', '🍍', '🍇', '🍏', '🍓', '🍎', '🍊', '🐴', '🐗', '🦄', '🐑', '🐶', '🐔', '🐼', '🐒', '🌝', '💄', '💋', '👠', '👗', '👙', '🧣', '🍰', '🍭', '🍳', '🎄', '🎱', '⚽', '🏀', '🎵', '🚄', '⭕', '❌', '❓', '❗', '💯'],
  // 标准颜色
  colors: {
    error: '#f7630c',
    warning: '#ca5010',
    info: '#0078d7',
    debug: '#13a10e',
    log: '#1f1f1f'
  },
  // 获取随机图标
  randomIcon: function () {
    return this.icons[Math.floor(Math.random() * this.icons.length)]
  },
  // 获取随机颜色
  randomColor: function () {
    const r = Math.floor(Math.random() * 256)
    const g = Math.floor(Math.random() * 256)
    const b = Math.floor(Math.random() * 256)
    // 返回随机生成的颜色
    return `rgb(${r}, ${g}, ${b})`
  },
  // 默认打印
  printDefault: function (tag, args) {
    console.log(tag, ...args)
  },
  // 标准打印
  printNormal: function (tag, args) {
    console.log(`%c ${tag} : `, `color: ${this.colors[tag]}`, ...args)
  },
  // 随机打印
  printRandom: function (tag, args) {
    const icon = this.randomIcon()
    const bgColor = this.randomColor()
    const color = this.randomColor()
    console.log(`%c ${icon}`, `font-size:20px;background-color: ${bgColor};color: ${color};`, tag + ' : ', ...args)
  },
  print: function (tag, args) {
    if (this.isPrintLine) {
      // 获取函数名和行号
      const err = new Error()
      // console.log(err.stack)
      const stack = err.stack.split('\n').slice(3).map(line => line.trim())
      const caller = stack[0].match(/at (.+) \(/) ? stack[0].match(/at (.+) \(/)[1] : stack[0].match(/at (.+):\d+:/)[1]
      const fileLine = stack[0].match(/\(.*\/(.+)\)/) ? stack[0].match(/\(.*\/(.+)\)/)[1] : stack[0].match(/(\d+:\d+)/)[1]
      // console.log(`${caller} (${fileLine}):\n`)

      args.push(`\n at : ${caller} (${fileLine})`)
    }

    switch (this.mode) {
      case 0: {
        this.printDefault(tag, args)
        break
      }
      case 1: {
        this.printNormal(tag, args)
        break
      }
      case 2: {
        this.printRandom(tag, args)
        break
      }
    }
  },
  error: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'error'
      if (this.level >= 1) {
        // oriLogFunc.call(console, 'error : ', args)
        this.print(tag, args)
      }
    }
  })(console.log),

  warning: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'warning'
      if (this.level >= 2) {
        // oriLogFunc.call(console, 'warning : ', args)
        this.print(tag, args)
      }
    }
  })(console.log),

  info: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'info'
      if (this.level >= 3) {
        // oriLogFunc.call(console, 'info : ', args)
        this.print(tag, args)
      }
    }
  })(console.log),

  debug: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'debug'
      if (this.level >= 4) {
        // oriLogFunc.call(console, 'debug : ', ...args)
        this.print(tag, args)
      }
    }
  })(console.log),

  log: (function (oriLogFunc) {
    return function (...args) {
      const tag = 'log'
      if (this.level >= 5) {
        // oriLogFunc.call(console, 'log : ', ...args)
        this.print(tag, args)
      }
    }
  })(console.log)
}

2. 测试

目录
在这里插入图片描述

  1. 新建一个html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>123123123</div>
    <button id="logBtn">log</button>
    <script type="module">
        import iceLog from './iceLog.js'
        window.onload = () => {
            window.iceLog = iceLog
            iceLog.log('hello new log')
            iceLog.debug('hello new debug')
            iceLog.info('hello new info')
            iceLog.warning('hello new warning')
            iceLog.error('hello new error')
        }

        document.getElementById('logBtn').addEventListener('click', () => {
            iceLog.log('click log button')
        })
    </script>
</body>
</html>
  1. 结果
    在这里插入图片描述

x. 参考

  1. 重写console.log方法
  2. 重写 console.log() 让其变的花里胡哨
  3. console.log格式输出全解及console的其他方法
  4. console 打印函数名和行号
  5. console.log输出打印日志所在代码行数
  6. 在html的script标签中使用import
  7. JS函数怎么实现传入任意数量参数?
  8. 重写console.log的一些理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/634776.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编译详细过程与交叉编译

GCC的编译过程&#xff1a; GCC编译分为四步&#xff0c;预处理、编译、汇编、链接。具体功能如上图所示&#xff0c;我们在稍微解释一下&#xff1a; 1.预处理&#xff1a; 实现过程&#xff1a;gcc -E xxx.c -o xxx.i 目的&#xff1a;我们的c程序中除了main函数以外&…

如何在Linux中使用read命令读取用户输入?——read命令实战

前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本文是专栏【linux基本功-基础命令实战】的第64篇文章。 专栏地址&#xff1a;[linux基本功-基础命令专栏] &#xff0c; 此专栏是沐风晓月对Linux常用命令的汇总&#xff0c;希望对你有用。 今天我们一…

实现jvm内存溢出

那么我们如何来构建一个堆内存溢出呢&#xff1f;其实很简单&#xff0c;我们只要定义一个List对象&#xff0c;然后通过一个循环不停的往List里面塞对象。因为只要Controller不被回收&#xff0c;那么它里面的成员变量也是不会被回收的。这样就会导致List里面的对象越来越多&a…

Play wright自动化测试工具该如何更加完美地使用

目录 1.1 拦截网络请求 1.2 pytest 管理用例 1.3 PO模型 1.4 API 和 UI 自动化测试融合 1.5 数据驱动 1.6 动态挑选用例执行 1.6 Allure测试报告 1.7 持续集成 1.1 拦截网络请求 网络拦截&#xff1a; 无响应 pass 中止 route.abort("aborted") 放行 route…

Hazel游戏引擎(013)Layers游戏的层级

文中若有代码、术语等错误&#xff0c;欢迎指正 文章目录 前言增加Layer后的主要类图项目相关代码项目流程效果 LayerStack类的错误 前言 此节目的 为完成008事件系统设计的第四步&#xff0c;将事件从Application传递分发给Layer层。 使引擎事件系统模块完整 Layer的理解 …

在VSCode下利用PlateFormIO开发Arduino的MicroROS遇到的一些问题

简介 我是按照鱼香ROS的教程【3.搭建PlateFormIO开发环境】进行的&#xff0c;但是在进行的过程中&#xff0c;遇到了一些问题&#xff0c;这里记录下来&#xff0c;供有同样问题的同学进行参考。其实只要你使用的板子的MCU是ESP32&#xff0c;都可以按照他这个教程进行操作。…

k8s实践之mysql集群搭建(十五)

先下载 k8s实践之mysql集群搭建资料 主从模式简介&#xff1a; 当master主服务器上的数据发生改变时&#xff0c;则将其改变写入二进制&#xff08;binlog&#xff09;事件日志文件中&#xff1b; slave从服务器会在一定时间间隔内对master主服务器上的二进制日志进行探测&am…

掌握Vue生命周期,让你的前端开发效率翻倍!

1 Vue实例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Vue实例</title><script src../vue.js></script> </head> <body><div id"root"><!-- v…

位图以及布隆过滤器

本文主要讲解哈希思想的实际应用&#xff0c;位图和布隆过滤器。 位图 讲解位图之前我们先来解答这样一道腾讯的面试题 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。【腾讯】 很多人立马就想到了用…

Seata TCC 模式理论学习、生产级使用示例搭建及注意事项 | Spring Cloud55

一、前言 通过以下系列章节&#xff1a; docker-compose 实现Seata Server高可用部署 | Spring Cloud 51 Seata AT 模式理论学习、事务隔离及部分源码解析 | Spring Cloud 52 Spring Boot集成Seata利用AT模式分布式事务示例 | Spring Cloud 53 Seata XA 模式理论学习、使用…

STL——set容器、map容器

初识STL **set容器/multiset容器****set容器——构造和赋值****set容器——大小和交换****set容器——插入和删除****set容器的查找和统计****set和multiset的区别****set的相关操作源码&#xff1a;****multiset的相关操作源码** **pair使用——pair队组的创建****set容器——…

FreeRTOS-定时器详解

✅作者简介&#xff1a;嵌入式入坑者&#xff0c;与大家一起加油&#xff0c;希望文章能够帮助各位&#xff01;&#xff01;&#xff01;&#xff01; &#x1f4c3;个人主页&#xff1a;rivencode的个人主页 &#x1f525;系列专栏&#xff1a;玩转FreeRTOS &#x1f4ac;保持…

2023全国计算机二级考试时间(全年各阶段考试时间安排)

2023全国计算机二级考试时间(全年各阶段考试时间安排) 2023年全国计算机二级考试时间分别为&#xff1a;3月25日至27日(上半年3月)、9月23日至25日(下半年9月)。 其中3月和9月开考全部级别全部科目&#xff0c;5月和12月考试开考一、二级全部科目&#xff0c;各省级承办机构可根…

RabbitMQ集群部署之镜像模式

RabbitMQ集群的普通模式中&#xff0c;一旦创建队列的主机宕机&#xff0c;队列就会不可用。不具备高可用能力。如果要解决这个问题&#xff0c;必须使用官方提供的镜像集群方案。 官方文档地址&#xff1a;https://www.rabbitmq.com/ha.html 1.镜像模式的特征 默认情况下&a…

离心式冷水机组

离心式冷水机组是利用电作为动力源&#xff0c;氟利昂制冷剂在蒸发器内蒸发吸收载冷剂水的热量进行制冷&#xff0c;蒸发吸热后的氟利昂湿蒸汽被压缩机压缩成高温高压气体&#xff0c;经水冷冷凝器冷凝后变成液体&#xff0c;经膨胀阀节流进入蒸发器再循环。从而制取7℃-12℃冷…

解决jvm内存溢出的方法

上一篇问题讲了怎么实现jvm内存溢出,现在已经实现了,那怎么去解决它呢. java.lang.OutOfMemoryError: GC overhead limit exceeded 简单来说&#xff0c;java.lang.OutOfMemoryError: GC overhead limit exceeded发生的原因是&#xff0c;当前已经没有可用内存&#xff0c;经…

【IMX6ULL驱动开发学习】06.APP与驱动程序传输数据_自动创建设备节点(hello驱动)

一、APP与驱动之间传输数据 /*驱动从APP获取数据*/ unsigned long copy_from_user(void *to, const void *from, unsigned long n)/*驱动传输数据到APP*/ unsigned long copy_to_user(void *to, const void *from, unsigned long n)二、使用copy_to_user、copy_from_user在AP…

如何把视频声音转成文字?分享三个实用的方法!

在日常学习中&#xff0c;有些小伙伴可能想将视频课程中老师的讲解内容整理出来&#xff0c;但是逐字逐句地打字既低效又耗时。那么&#xff0c;如何将视频声音快速转换为文字呢&#xff1f;答案是使用记灵在线工具&#xff01;下面我将分享几种使用记灵在线工具快速将视频声音…

Raft is not great?

Raft相比于paxos不好的地方有下面这些地方 1.Term raft的逻辑时钟是通过term&#xff0c;和votefor来确定的&#xff0c;同时&#xff0c;raft的votefor只能是None < 有&#xff0c;有的话&#xff0c;就不可比&#xff0c;也就是一个偏序关系。这个不可比的特性会增加选举…

Javaweb学习路线(2)——Maven

一、概念 Maven 是 apache 旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具。 二、作用 依赖管理&#xff1a; 动态管理jar包&#xff0c;避免版本冲突。统一项目结构&#xff1a; 提供标准、统一的项目结构。项目构建&#xff1a; 标准跨平台的自动化项目…