我们应该在JavaScript API中验证方法参数吗?

Tot*_*ach 16 javascript validation

我正在开发一个将由第三方开发人员使用的JavaScript库.API包含具有此签名的方法:

function doSomething(arg1,arg2,options)

  • arg1,arg2是'required'简单类型参数.
  • options是包含可选参数的哈希对象.

您是否建议验证: - 参数类型是否有效? - 选项属性是否正确?例如:开发人员没有错误地通过onSucces而不是onSuccess?

  • 为什么像prototype.js这样的热门库不能验证?

xto*_*ofl 11

您有权决定是制作"防御性"还是"合同性"API.在许多情况下,阅读库的手册可以使用户明白他应该提供遵循这些和那些约束的这种或那种类型的参数.

如果您打算创建一个非常直观,用户友好的API,那么验证您的参数会很不错,至少在调试模式下是这样.但是,验证需要花费时间(和源代码=>空间),因此将其删除也可能会很好.

由你决定.


Aar*_*lla 8

尽可能多地验证并打印有用的错误消息,帮助人们快速轻松地追踪问题.

引用此验证代码并附带一些特殊注释(例如//+++VALIDATE//--VALIDATE),以便您可以使用高速压缩生产版本的工具轻松删除它.

  • 生产中的高速失败? (3认同)
  • 在生产代码中,早期失败通常不再那么重要,因为大多数错误已得到修复.也就是说,如果您使用我的方法,您可以轻松创建一个较慢的验证版本,并在需要时将其部署到生产中. (2认同)

Tot*_*ach 4

感谢您的详细解答。

下面是我的解决方案 - 一个用于验证的实用程序对象,可以轻松扩展以验证基本上任何内容...代码仍然足够短,因此我不需要在生产中解析它。

WL.Validators = {

/*
 * Validates each argument in the array with the matching validator.
 * @Param array - a JavaScript array.
 * @Param validators - an array of validators - a validator can be a function or 
 *                     a simple JavaScript type (string).
 */
validateArray : function (array, validators){
    if (! WL.Utils.isDevelopmentMode()){
        return;
    }
    for (var i = 0; i < array.length; ++i ){            
        WL.Validators.validateArgument(array[i], validators[i]);
    }
},

/*
 * Validates a single argument.
 * @Param arg - an argument of any type.
 * @Param validator - a function or a simple JavaScript type (string).
 */
validateArgument : function (arg, validator){
    switch (typeof validator){
        // Case validation function.
        case 'function':
            validator.call(this, arg);
            break;              
        // Case direct type. 
        case 'string':
            if (typeof arg !== validator){
                throw new Error("Invalid argument '" + Object.toJSON(arg) + "' expected type " + validator);
            }
            break;
    }           
}, 

/*
 * Validates that each option attribute in the given options has a valid name and type.
 * @Param options - the options to validate.
 * @Param validOptions - the valid options hash with their validators:
 * validOptions = {
 *     onSuccess : 'function',
 *     timeout : function(value){...}
 * }
 */
validateOptions : function (validOptions, options){
    if (! WL.Utils.isDevelopmentMode() || typeof options === 'undefined'){
        return;
    }
    for (var att in options){
        if (! validOptions[att]){
            throw new Error("Invalid options attribute '" + att + "', valid attributes: " + Object.toJSON(validOptions));
        }
        try {
            WL.Validators.validateArgument(options[att], validOptions[att]);
        }
        catch (e){
            throw new Error("Invalid options attribute '" + att + "'");
        }
    }   
},
Run Code Online (Sandbox Code Playgroud)

};

以下是我如何使用它的一些示例:

isUserAuthenticated : function(realm) {
WL.Validators.validateArgument(realm, 'string');



getLocation: function(options) {            
    WL.Validators.validateOptions{
        onSuccess: 'function', 
        onFailure: 'function'}, options);


makeRequest : function(url, options) {
    WL.Validators.validateArray(arguments, ['string', 
        WL.Validators.validateOptions.carry({
        onSuccess : 'function', 
        onFailure : 'function',
        timeout   : 'number'})]);
Run Code Online (Sandbox Code Playgroud)