实现 console.log 代理方法
定义 log 方法代理 console.log,支持参数透传
问题
定义一个 log 方法,让它可以代理 console.log 的方法。
解答
基础实现
// 方式一:使用 rest 参数 + spread 语法
function log(...args) {
console.log(...args);
}
// 方式二:使用 apply 转发参数
function log() {
console.log.apply(console, arguments);
}
// 方式三:直接绑定
const log = console.log.bind(console);
// 测试
log('hello'); // hello
log('a', 'b', 'c'); // a b c
log({ name: 'test' }); // { name: 'test' }
增强版:添加前缀和时间戳
function createLogger(prefix = '') {
return function(...args) {
const time = new Date().toLocaleTimeString();
// 在原有参数前添加时间和前缀
console.log(`[${time}]${prefix}`, ...args);
};
}
const log = createLogger('[App]');
log('启动成功'); // [10:30:45][App] 启动成功
log('用户数:', 100); // [10:30:45][App] 用户数: 100
完整代理:支持所有 console 方法
const logger = {};
// 代理 console 的所有方法
['log', 'warn', 'error', 'info', 'debug'].forEach(method => {
logger[method] = function(...args) {
const time = new Date().toLocaleTimeString();
console[method](`[${time}]`, ...args);
};
});
// 测试
logger.log('普通日志'); // [10:30:45] 普通日志
logger.warn('警告信息'); // [10:30:45] 警告信息
logger.error('错误信息'); // [10:30:45] 错误信息
使用 Proxy 实现
const logger = new Proxy(console, {
get(target, prop) {
if (typeof target[prop] === 'function') {
return function(...args) {
const time = new Date().toLocaleTimeString();
// 调用原始方法,添加时间前缀
target[prop].call(target, `[${time}]`, ...args);
};
}
return target[prop];
}
});
logger.log('test'); // [10:30:45] test
logger.warn('warn'); // [10:30:45] warn
关键点
- 使用
...argsrest 参数收集所有参数,再用 spread 展开传递 apply可以将类数组arguments作为参数列表传递bind返回绑定了this的新函数,最简洁- 代理模式可以在不修改原方法的情况下增加功能(如日志时间、前缀)
Proxy可以拦截对象的所有属性访问,实现更灵活的代理
目录