我读过一个在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()函数并不像预期的那样工作。我的问题是,有没有什么诀窍可以让它工作。
发布于 2017-07-06 18:15:47
当然它不能工作,我想你误解了Default Parameters是如何工作的。
当你写的时候
function foo(mustBeProvided = throwIfMissing())当且仅当参数为时,您将throwIfMissing的结果赋给参数。
这意味着如果提供了该参数,则throwIfMissing是,而不是调用;它永远不会执行,也永远不会检查参数的有效性。
这就是为什么你只能使用这个“技巧”来对一个未定义的参数做出反应,而不是验证一个参数。
--
替代解决方案
就我个人而言,我会用一个简单的解决方案来解决这个问题。
function checkRange(val, min, max) {
if (val > max || val < min) {
throw new Error();
}
}
function foo(val) {
checkRange(val, 5, 10);
return val;
} 您可能会认为这不是很优雅,但请记住,在这种情况下,您可以重用具有不同值的验证器,您不必硬编码min和max。
如果你正在寻找一个npm模块,你可以尝试this one,但我不会为了一个简单的验证走那么远。
发布于 2017-07-06 18:14:07
这种技巧只适用于一般的错误消息,并且不能强制特定于它正在检查其参数的函数,因为从一开始就没有提供参数。
现在,给你上一课:
考虑一下这种情况:
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函数需要一个对象,然后它尝试访问该对象的value键,由于参数为undefined,它将失败,并且整个代码链将停止。这在很大程度上是不必要的,可以避免。上面的例子只有在对象有value键的情况下才有效,如下所示:
console.log( foo({value:1}) )发布于 2020-02-06 07:45:45
正如其他答案所指出的,在您提供的示例中,只有在未传递参数时才会触发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
https://stackoverflow.com/questions/44945586
复制相似问题