关于代理:链式调用与proxy

34次阅读

共计 1878 个字符,预计需要花费 5 分钟才能阅读完成。

链式调用尽管高兴,可每个办法前面的 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();

正文完
 0