我已经在2ality上阅读了处理所需功能参数的绝佳模式。
function throwIfMissing() {
throw new Error('Missing parameter');
}
function foo(mustBeProvided = throwIfMissing()) {
return mustBeProvided;
}
有没有这样漂亮而干净的方法来抛出验证错误?
function throwIfInvalid(value) {
const max = 10;
const min = 5;
if(value < min || value > max){
throw new Error(`Value must be between ${min} ${max}`);
}
return value;
}
function foo(mustBeValid = throwIfInvalid()) {
return mustBeValid;
}
当然throwIfInvalid()
函数不能按预期工作。我的问题是,是否有任何技巧可以使其发挥作用。?
答案 0 :(得分:2)
当然它不起作用,我认为你误解了Default Parameters的工作方式。
写作时
function foo(mustBeProvided = throwIfMissing())
您要将throwIfMissing
的结果分配给参数 IF仅在参数为undefined
。
这意味着如果提供了该参数,则throwIfMissing
根本不会被调用;它永远不会执行,也永远不会检查参数的有效性。
这就是为什么你只能使用这个&#34;技巧&#34;对未定义的参数作出反应,而不是对其进行验证。
-
替代解决方案
我个人会用一个简单的解决方案解决问题
function checkRange(val, min, max) {
if (val > max || val < min) {
throw new Error();
}
}
function foo(val) {
checkRange(val, 5, 10);
return val;
}
您可能会认为这不那么优雅,但请记住,在这种情况下,您可以重复使用具有不同值的验证器,您不必硬编码最小值和最大值。
如果您正在寻找一个npm模块,您可以尝试this one但我不会那么做以进行简单的验证。
答案 1 :(得分:1)
此技巧仅适用于通用错误消息,并且不能强制特定于检查其参数的函数,因为参数从未首先提供。
考虑这种情况:
function missingArgument() {
console.warn('Missing parameter');
}
function foo(bar = missingArgument()){
return bar.value;
}
console.log( foo() ) // will throw an error since "bar" is not a value
console.log('end'); // never reach here
上面的例子会抛出一个错误,但missingArgument
函数的技巧并不是很有用,因为它不会立即告诉你问题在哪里。您可以传递一个字符串,该字符串将提供有用的信息:
function missingArgument(name) {
console.warn('Missing parameter in function:', name);
}
function foo(bar = missingArgument('foo')) {
return bar.value;
}
console.log(foo()) // will throw an error since "bar" is not a value
console.log('end'); // never reach here
这可以通过这种方式解决:
function missingArgument() {
console.warn('Missing parameter');
}
function foo(bar = missingArgument()){
if( bar == undefined ) return 0;
return bar.value;
}
console.log( foo() )
console.log('end');
每个函数显然都有自己的功能,所以你必须知道函数应该对期望的参数做什么,函数的预期输出是什么,然后在它的开头定制你的保护。
上面的foo
函数期待一个Object,然后它尝试访问该对象的value
键,并且由于参数为undefined
,它将失败并且整个代码链即将结束。这主要是不需要的,可以避免。
上面的示例仅在Object具有value
键时才有效,如下所示:
console.log( foo({value:1}) )
答案 2 :(得分:0)
正如其他答案所指出的那样,在您提供的示例中,throwIfInvalid()
仅在未传递参数时才会被触发。因此,您不能像在下一个示例中那样使用它。
但是,如果您必须使用类似的东西,我只会想到以下内容:
function isValidNumber(value, min = 5, max = 10) {
if(isNaN(value) || value < min || value > max) {
throw new Error(`Value must be a number between ${min} ${max}`);
}
return true;
}
function foo(mustBeValid, isValid = isValidNumber(mustBeValid)) {
return mustBeValid;
}
try {
// This will return '7'
var bar = foo(7);
// Showing the value in the screen
document.write(bar);
// This will throw an error
bar = foo(1);
} catch (e) {
document.write('<br><br>'+e);
}
但是,我宁愿只是在开始时将验证方法作为保护子句。或者,您也可以结帐Proxy
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#Validation