Уже есть отличные ответы, чтобы stringLengths
работал с любым количеством параметров.Однако все (пока) предполагают, что каждый параметр является строкой.
, что может привести к неожиданным результатам:
- И массивы, и функции имеют свойство
length
- Любые объекты могут быть обработаны с помощью свойства
length
Или даже ошибок:
- Такие вещи, как
null
или undefined
вызовут ошибку, когдапытается прочитать свойства из них.
const stringLengths = (...strs) =>
strs.map(s => s.length);
console.log(
stringLengths(1, 2)
);
console.log(
stringLengths({length: '?'}, ['?'], (a, b) => '?')
);
console.log(
stringLengths(null, null)
);
Вы можете написать декоратор filterStrings
, который можно применить к stringLengths
, чтобы он получал только строки:
const stringLengths = (...strs) =>
strs.map(s => s.length);
const filterStrings = fn => (...args) =>
fn(...args.filter(arg => typeof arg === 'string'));
const safeStringLengths = filterStrings(stringLengths);
console.log(
safeStringLengths(1, 2)
);
console.log(
safeStringLengths({length: '?'}, ['?'], (a, b) => '?')
);
console.log(
safeStringLengths(null, null)
);
console.log(
safeStringLengths("foo", "bar", "foobar")
);
filterStrings
- это функция, которая фактически получает все параметры, сохраняет только строки и передает их stringLengths
.
Почему так?
Это действительно зависит от вашего контекста.Хорошая особенность декоратора состоит в том, что он позволяет вам переместить проверку параметров за пределы stringLengths
и позволить функции делать только одно.
В некоторых сценариях вы можете просто доверять своим параметрам и иметь проверкув вашей функции было бы бесполезно.В других случаях вы не можете.Возможность комбинировать функции позволяет вам держать вещи разделенными и организованными.