《JavaScript权威指南》trace函数调用报错:Uncaught TypeError: trace(...) is not a function 求解
问题分析与解决方案
你遇到的Uncaught TypeError: trace(...) is not a function错误,核心原因是**trace()的设计定位和timed()完全不同**——它是用来包装对象的方法,而非独立函数,所以你的调用方式不符合它的预期。
为什么你的代码会报错?
先看trace()的定义:它接收两个参数,第一个是包含目标方法的对象o,第二个是方法名的字符串m。它的作用是修改对象o上的m方法,替换为带日志的版本,但它本身没有返回值(或者说返回undefined)。
你写的trace(benchmark)(1000000)犯了两个错误:
- 第一个参数传了独立函数
benchmark,而不是包含该方法的对象; - 因为
trace()返回undefined,你紧接着加(1000000)就相当于调用undefined(),自然会抛出“不是函数”的错误。
正确的使用方式
trace()是为对象方法设计的,所以你需要先把benchmark变成某个对象的方法,再用trace包装它,最后调用对象上的方法。示例代码如下:
function trace(o, m) { let original = o[m]; o[m] = function(...args) { console.log(new Date(), "Entering:", m); let result = original.apply(this, args); console.log(new Date(), "Exiting:", m); return result; }; } // 1. 把benchmark变成对象的方法 const myUtils = { benchmark(n) { let sum = 0; for(let i = 1; i <= n; i++) sum += i; return sum; } }; // 2. 用trace包装myUtils上的benchmark方法(第二个参数是方法名字符串) trace(myUtils, 'benchmark'); // 3. 调用对象上的包装后的方法 myUtils.benchmark(1000000);
运行这段代码,控制台会输出类似:
2024-05-20T12:34:56.789Z Entering: benchmark 2024-05-20T12:34:56.835Z Exiting: benchmark
和timed()的核心区别
timed():接收一个独立函数,返回一个新的包装函数,所以可以直接链式调用timed(benchmark)(1000000);trace():直接修改对象上的现有方法,没有返回可调用的函数,必须分两步:先调用trace()完成包装,再调用对象的方法。
你尝试的变体为什么不对?
benchmark.trace(1000000):benchmark是普通函数,默认没有trace方法;trace.benchmark(1000000):trace是函数本身,也不存在benchmark方法;benchmark.call(trace, 1000000):这只是把trace作为this上下文调用benchmark,和trace函数的日志包装功能无关;trace(obj, benchmark(1000000)):第二个参数需要传入方法名的字符串,你却传了benchmark(1000000)的返回值(一个数字),完全不符合参数要求。
内容的提问来源于stack exchange,提问作者maxloo
相关产品推荐
相关产品推荐

