首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ES6函数参数验证

ES6函数参数验证
EN

Stack Overflow用户
提问于 2017-07-06 17:53:55
回答 3查看 5.3K关注 0票数 0

我读过一个在2ality上处理所需函数参数的很好的模式。

代码语言:javascript
复制
function throwIfMissing() {
    throw new Error('Missing parameter');
}
function foo(mustBeProvided = throwIfMissing()) {
    return mustBeProvided;
}

有没有这么好又干净的方法来抛出验证错误呢?

代码语言:javascript
复制
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()函数并不像预期的那样工作。我的问题是,有没有什么诀窍可以让它工作。

EN

回答 3

Stack Overflow用户

发布于 2017-07-06 18:15:47

当然它不能工作,我想你误解了Default Parameters是如何工作的。

当你写的时候

代码语言:javascript
复制
function foo(mustBeProvided = throwIfMissing())

当且仅当参数为时,您将throwIfMissing的结果赋给参数

这意味着如果提供了该参数,则throwIfMissing是,而不是调用;它永远不会执行,也永远不会检查参数的有效性。

这就是为什么你只能使用这个“技巧”来对一个未定义的参数做出反应,而不是验证一个参数。

--

替代解决方案

就我个人而言,我会用一个简单的解决方案来解决这个问题。

代码语言:javascript
复制
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,但我不会为了一个简单的验证走那么远。

票数 3
EN

Stack Overflow用户

发布于 2017-07-06 18:14:07

这种技巧只适用于一般的错误消息,并且不能强制特定于它正在检查其参数的函数,因为从一开始就没有提供参数。

现在,给你上一课:

考虑一下这种情况:

代码语言:javascript
复制
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函数的技巧没有太大帮助,因为它不会立即告诉您问题出在哪里。您可以传递一个字符串,它将提供有用的信息:

代码语言:javascript
复制
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

这可以通过以下方式解决:

代码语言:javascript
复制
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键的情况下才有效,如下所示:

代码语言:javascript
复制
console.log( foo({value:1}) )
票数 1
EN

Stack Overflow用户

发布于 2020-02-06 07:45:45

正如其他答案所指出的,在您提供的示例中,只有在未传递参数时才会触发throwIfInvalid()。因此,您不能像在下一个示例中那样使用它。

然而,如果你一定要使用类似的东西,我只能想到以下几点:

代码语言:javascript
复制
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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44945586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档