javascript - JavaScript: TypeError: work.calls is not iterable in function decorator (beginner question)
问题描述
I was trying to pass a function work
into a decorator where it will save function calls in an array work.calls
.
The function:
work(a, b) {
console.log(a + b);
}
The decorator:
function decorator(func) {
func.calls = [];
return function(...args) {
func.calls.push(args);
return func.call(this, ...args);
}
}
Decorate function work
:
work = decorator(work);
Calling new function:
work(1, 2); // 3
work(4, 5); // 9
for (let args of work.calls) {
console.log( 'call:' + args.join() ); // TypeError: work.calls is not iterable
}
work.calls
is an array so why is it not iterable?
For reference, there's another version of decorator written by someone else that actually works:
function decorator(func) {
function wrapper(...args) {
wrapper.calls.push(args);
return func.apply(this, arguments);
}
wrapper.calls = [];
return wrapper;
}
work(1, 2); // 3
work(4, 5); // 9
for (let args of work.calls) {
alert( 'call:' + args.join() ); // "call:1,2", "call:4,5"
}
What does wrapper
do here and why this way works?
解决方案
The 2 functions do not work the same. Your decorator defines the calls
property on the passed function. The other decorator function sets the property on the nested and returned (wrapper
) function. You get that error as work.calls
is undefined
. The decorated work
refers to the anonymous function: return function(...args)
which doesn't have calls
property.
If you change work = decorator(work);
to let work2 = decorator(work);
then you will see that calls
is set on the original work
function and not on work2
.
Your code works the same if you define the calls
property on the returned function of the closure.
function decorator(func) {
function __(a, b) {
__.calls.push([a, b])
return func(a, b)
}
__.calls = []
return __;
}
推荐阅读
- c++ - 如何使用 Poco::ZIP 压缩/解压缩 zip 文件
- azure - Webhook 调用失败。错误:PERMISSION_DENIED。dialogflow webhook 调用错误
- mysql - 可快速搜索的同义词
- javascript - 从导航栏链接(内部 php / html 文件)到同一页面内的主要部分
- javascript - 这是 intl.dateTimeFormat 错误吗?
- python - 如何在特殊情况下提取两个关键字之间的子字符串?
- android - 无法将 ImageView 中加载的图像上传到 Firebase
- firebase - Firebase 存储 API 触发两次
- javascript - 如何在 Gatsby 插件中使用 React 组件?
- javascript - 没有从机器人模拟器获取数据到 blob 存储?