链式调用尽管高兴,可每个办法前面的 return this
略显繁琐与俊俏,括号与引号也未免太多。
例如上面这个简略的logger
new Logger() .addLabel("warn", "l4", "登录", "游客", "error") .addContent("失败") .addContent("明码不对") .end();
你可能曾经对这样的封装司空见惯了,但其实他还能这样写!
Log.warn.l4.label("登录", "游客").log("失败").error.明码不对;
我感觉后者有一种简洁美
具体实现如下
class Logger { label: string[] = []; content: unknown[] = []; addLabel(...label: string[]) { this.label.push(...label); return this; } addContent(content: unknown) { this.content.push(content); return this; } end() { // 做一些存储打印之类的操作 console.log(this); }}function getLog() { const logger = new Logger(); /** 拜访链路 */ const propertyLink: (string | number | symbol)[] = []; const self = (new Proxy(/** 指标不重要,因为实际上应用 target */ getLog, { get(target, property, receiver) { propertyLink.push(property); // console.log(property); if (/** 表等级用 */ typeof property === "string" && /l\d+/.test(property)) { logger.addLabel(property); } else if (/** 间接增加标签 */ typeof property === "string" && ["warn", "error"].includes(property)) { logger.addLabel(property); } else if (/** 能够调用的办法 */ typeof property === "string" && ["log", "label"].includes(property)) { // 调用则增加内容 } else { //over logger.addContent(property); return logger.end(); } return self; }, apply(target, thisArg, argumentsList) { const previousProperty = propertyLink[propertyLink.length - 1]; if (previousProperty === "label") { logger.addLabel(...argumentsList); } else if (previousProperty === "log") { logger.addContent(argumentsList); } return self; }, }) as any) as Log; return self;}const Log = new Proxy(getLog(), { get() { return getLog(); },});type Log = { error: Log; warn: Log; info: Log; label: (...lables: string[]) => Log; l1: Log; l2: Log; l3: Log; l4: Log; l5: Log; l6: Log; l7: Log; l8: Log; l9: Log; /** 具体音讯 */ [k: string]: void | Log | any; log: (...arg: unknown[]) => Log; end: void;};Log.error.l9.错了呀;Log.error.l9.warn.错了呀;Log.error.l4.那天夕阳下的奔跑是我逝去的青春;Log.warn.l4.log("有毒?").end;Log.warn.l4 .label("登录") .label("游客") .log("失败").end;Log.warn.l4.label("登录", "游客").log("失败").error.明码不对;new Logger() .addLabel("warn", "l4", "登录", "游客", "error") .addContent("失败") .addContent("明码不对") .end();