#javascript #object #callback #closures #memoization
#javascript #объект #обратный вызов #замыкания #запоминание
Вопрос:
Итак, я использую внутреннюю функцию для закрытия и для передачи неизвестного количества аргументов. Предполагается, что функция использует какую-то запоминание (я решил использовать объект), чтобы проверить и посмотреть, были ли результаты выполнения аргументов через обратный вызов уже вычислены и сохранены. Вот функция, которую я написал до сих пор…
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' }));
});
Если у вас есть время. Я был бы признателен, если бы знал, почему моя текущая функция не работает с объектами в качестве аргументов… Кроме того, как я могу изменить то, что я написал, чтобы удовлетворить алгоритм тестирования.
Комментарии:
1. Ключи объекта должны быть строками, а не объектами.
2. Хорошо, так что именно это означает в моем случае?
3. Это означает, что вы не должны использовать это для функций с аргументами объекта. Или, может быть, вы могли бы изменить ключ на
JSON.stringify(arg)
4. Спасибо! Это сработало! Теперь мне просто нужно прочитать об этом и выяснить, почему lol!
Ответ №1:
Имена свойств являются строковыми или символьными. Любое другое значение, включая число, преобразуется в строку. Это выводит «значение», поскольку 1 преобразуется в «1». См. Средства доступа к свойствам
Поэтому, когда вы вызываете obj[arg]
, вы на самом деле вызываете что-то вроде obj[arg.toString()]
. Вот arg
массив аргументов, например [{foo: 'bar'}]
. Попробуйте вызвать [{foo: 'bar'}].toString()
, и вы получите [object Object]
. См. Array.prototype .toString() и Object.prototype .toString() .
Это означает, что для каждого аргумента объекта вы получите один и тот же ключ.
Комментарии:
1. Спасибо, что нашли время объяснить, почему он не работал с объектами в качестве аргументов!
2. Если вы печатаете свой объект кэша при отладке кода, вы, возможно, уже нашли это.