抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

Typescript的装饰器使用起来太优雅了,想加什么功能直接装饰上就好了。

效果

实现了两种版本的修改console.log默认的打印样式方法。

效果就是可以打印五颜六色的字体。

387189C1D2942091FB4EE274D076BB14

throw Error 版

const fancy_console: MethodDecorator =
    (_a, _b, descriptor: PropertyDescriptor) => {
        // 取出被装饰的方法
      	const method = descriptor.value
        // “装饰”该方法
        descriptor.value = function () {
            try {
                method.apply(this, arguments)
            } catch (e: any) {
                const r = (Math.random() * 255) | 0
                const g = (Math.random() * 255) | 0
                const b = (Math.random() * 255) | 0

                console.log(`%c${e.message}`, `color:rgb(${r},${g},${b});font-size:16px`);
            }
        }
    }

测试代码:

class Test {
    value = 1;
    @fancy_console
    method() {
        console.log(this);	// Test { value: 1 }

        throw new Error("haha") // haha
        throw new Error("haha") // 


    }
}
(new Test).method()

throw new Error() 这种方式虽然结构上很完美,但是只能打印一次,第二次throw的时候代码已经执行完了。

所以干脆在类上添加一个 log 方法,打印的时候调自己写的 log 方法。

自定义 log 方法版

const fancy_console: ClassDecorator =
    (target: Function) => {
      	// 在被装饰的原型对象上添加 log 方法
        target.prototype.log = function (content: string) {
            const r = (Math.random() * 255) | 0
            const g = (Math.random() * 255) | 0
            const b = (Math.random() * 255) | 0
            console.log(`%c${content}`, `color:rgb(${r},${g},${b});font-size:16px`);
        }
    }
// 防止报log不存在的Error
interface Test {
    log: Function
}

@fancy_console
class Test {
    value = 1;
    method() {
        console.log(this);
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
        this.log("我就是我")
    }
}
(new Test).method()

效果如文章开头截图。

这种方式我比较满意了。

Node.js 专用版

最近写Nodejs 发现打印对象和函数的时候不会具体地打印其内容,而是这样:

console.log({ name: 1, child: [{ obj: { key: 1 } }] })	
// { name: 1, child: [ { obj: [Object] } ] }
console.log(function () { console.log(123) })
// [Function (anonymous)]
console.log([1, 23, 231123, 314, [34, 23]])
// [ 1, 23, 231123, 314, [ 34, 23 ] ]

非常影响阅读!

装饰器实现:

import { js_beautify } from "js-beautify";
const fancy_console: ClassDecorator =
    (target: Function) => {
        target.prototype.log = function (content: string | Function | object) {
            let message = content;
            if (typeof message === "object") {
              	// 对象类型——使用JSON格式化
                message = JSON.stringify(message, null, 2)
            } else if (typeof message === "function") {
              	// 函数代码——调用模块fromat
                message = js_beautify(message.toString(), 
                                      { indent_size: 2, space_in_empty_paren: true })
            }
          	// 打印处理结果
            console.log(message);
        }
    }

interface Test {
    log: (content: string | Function | object) => void
}

同样的在类上使用装饰器,效果:

// 对象
{
  "name": 1,
  "child": [
    {
      "obj": {
        "key": 1
      }
    }
  ]
}
// 函数代码
function() {
  console.log(123);
}
// 二维数组
[
  1,
  23,
  231123,
  314,
  [
    34,
    23
  ]
]

瞬间清晰了许多!

评论