尝试使用记忆对象来检查参数是否已经计算...似乎无法处理使用对象作为参数

Trying to use memoization object to check if an argument has already been computed... can't seem to handle using objects as arguments

提问人:DaShaman 提问时间:12/9/2021 更新时间:12/9/2021 访问量:381

问:

因此,我使用内部函数进行闭包,并能够传入未知数量的参数。该函数应该使用某种记忆(我选择使用对象)来检查并查看是否已经计算和存储了通过回调运行参数的结果。这是我到目前为止编写的函数......

function memoize(func) {
    // Define an object to hold results
    let obj = {}
    // define an inner function for closure that takes an argument
    function inner(...arg) {
        if (obj[arg]) {
            return obj[arg]
        } else {
            obj[arg] = func(...arg);
            return obj[arg];
        }
    }
    return inner;
}

我收到一个错误,我的函数“应该使用对象作为参数”......目前,我不确定为什么我当前的代码不能将对象用作参数......因此,如果有人能解释这一点,将不胜感激。这是用于测试我的函数的算法......

it('should work with objects as arguments', () => {
    const firstTime = timeCheck({ foo: 'bar' });
    wait(5);
    const secondTime = fastTimeCheck({ foo: 'bar' });
    wait(5);
    expect(firstTime).to.not.equal(secondTime);
    expect(fastTimeCheck({ foo: 'bar' })).to.equal(secondTime);
    expect(fastTimeCheck({ foo: 'bar' })).to.not.equal(fastTimeCheck({ different: 'result' }));
  });

如果你有时间。我很高兴知道为什么我当前的函数不能将对象作为参数使用......另外,我怎样才能修改我写的内容以满足测试算法。

JavaScript 对象 回调 闭包记忆

评论

1赞 Barmar 12/9/2021
对象键必须是字符串,而不是对象。
0赞 DaShaman 12/9/2021
好的,那么这在我的情况下究竟意味着什么?
1赞 Barmar 12/9/2021
这意味着您不应该将其用于具有对象参数的函数。或者,也许您可以将密钥更改为JSON.stringify(arg)
0赞 DaShaman 12/9/2021
谢谢!那奏效了!现在我只需要阅读它并弄清楚为什么哈哈!

答:

1赞 Xiaofeng Zheng 12/9/2021 #1

属性名称为 string 或 Symbol。任何其他值(包括数字)都会强制转换为字符串。这将输出“值”,因为 1 被强制转换为“1”。请参阅属性访问器

所以当你打电话时,你实际上叫类似的东西。下面是参数的数组,例如 .尝试打电话,你会得到.请参阅 Array.prototype.toString() 和 Object.prototype.toString()。obj[arg]obj[arg.toString()]arg[{foo: 'bar'}][{foo: 'bar'}].toString()[object Object]

这意味着对于每个对象参数,您将获得相同的键。

评论

0赞 DaShaman 12/9/2021
感谢您花时间解释为什么它不能将对象用作参数!
0赞 Xiaofeng Zheng 12/9/2021
如果在调试代码时打印缓存对象,则可能已经找到了缓存对象。