理解和纠正Javascript代码的结构

时间:2014-10-16 14:51:40

标签: javascript jquery

所以我已经在这里待了一段时间,而且我仍然被认为是基于我对结构和基本概念的一般知识的入门级程序员。我在下面给出了一个功能,在我回答我提出的另一个问题的答案中。我可以理解它正在做的大部分内容,但我需要帮助理解它的其余部分。我之所以这样问是因为我真的想了解javascript和jQuery的更高级概念。

所以我在下面所做的就是放置这个功能,然后我会对我所知道的功能在哪里做什么进行评论,然后我会在我所在的地方放置问号&# 34;混淆了。

function validate(){
    //array of objeccts used to defined the class selector for each element iterated
    //with what validation function is be assigned to that specific selector
    var fields = [
        {
            selector: $('.not-empty'),
            validations: [ isNotEmpty]
        },
        {
            selector: $('.email'),
            validations: [ isNotEmpty, isEmail]
        },
        {
            selector: $('.number'),
            validations: [ isNotEmpty, isNumber]
        },
        {
            selector: $('.number-noreq'),
            validations: [isNumberNotRequired]
        },
        {
            selector: $('.checked'),
            validations: [isChecked]
        }
    ];
    //remove any classes of 'has-error' from each element traversed before validation begins
    $('.form-control').closest('.form-group').removeClass('has-error');
    //defining variables
    var i = 0, k = 0, z = 0, j = fields.length, item, selector, fn, info;
    //for loop to traverse the fields array of objects
    for(; i < j; i++){
        item = fields[i];
        //traversing each field.validation
        for(k = 0; k < item.validations.length; k++){
            fn = item.validations[k]; //setting fn as a function found in validation
            //traversing each selector in item
            for( z = 0; z < item.selector.length; z++){
                selector = $(item.selector[z]); //setting the selector
                //attempting to set info to the closest form or input group found by the selector
                info = selector.closest('.form-group, .input-group');
                if(info) //if info contains data
                    //?????????????????????????????????????? no idea what's going on below other
                    //other than it's running the validation function that was passed, but why
                    //is it written like this and what is it doing?
                    info[fn(selector.val()) ? 'removeClass' : 'addClass']('has-error');
            }
        }
    }
}

这就是我对此代码的基本问题(所有问号都在哪里)。如果某人能够清楚地回答正在发生的事情,那么为什么要编写这样的代码,它的目的是什么,以及它是否有益,将是非常棒的。如果您需要更多说明,我很乐意提供。我只是希望能够向某人解释代码并知道我在说什么,而不是试图通过它来解决问题。我认为这是爱因斯坦所说的,如果你不能准确地解释一些事情,那么你真的不理解它&#34;或类似的东西!

提前谢谢!

编辑:以下是验证功能&#39;遍历

//validation functions
function isNotEmpty(value){
    return value && $.trim(value).length > 0;
}
function isEmail(value){
    return /^([^@\s\t\n]+\@[\w\d]+\.[\w]{2,3}(\.[\w]{2})?)$/.test(value);
}

function isNumber(value){
    return /^\d+$/.test(value);   
}
function isNumberNotRequired(value){
    return /^\d+$/.test(value) || value.length < 1;
}
 function isChecked(value){
    var r = false;
    var name = $(value).attr('name');
    $('input[name="'+name+'"').each(function(){
    if($(this).is(':checked')){
        r = true;       
    }
    });
    return r;
}

第二次编辑/更新:我们已确定代码中存在严重错误,导致其无法跟踪验证并考虑输入组和其他相关部分的先前验证。这是如何纠正的。当我有恢复的时候,我会在jsfiddle上测试物品!

2 个答案:

答案 0 :(得分:2)

这一行:

   info[fn(selector.val()) ? 'removeClass' : 'addClass']('has-error');

相当于:

   var result = fn(selector.val());
   if (result)
     info.removeClass("has-error");
   else
     info.addClass("has-error");
那是怎么回事?好吧,您的代码调用从该数据结构中存储的验证例程列表中提取的函数,并传递要测试的字段的值。该函数调用的结果用作? :表达式中的真/假测试。如果结果为true,则? :会解析为字符串"removeClass"; if false"addClass"

现在,info是什么?它是一个jQuery对象,它指的是最接近DOM的部分(可能)是显示错误消息的位置,或者是基于某些CSS规则显示某些其他指示符的地方。 [ ]运算符将接受? :解析的这两个字符串中的任何一个,并将其用作属性访问器。因此,净效应是引用info.removeClassinfo.addClass。这些都是对jQuery方法的引用,因此将调用其中一个或另一个。在任何一种情况下,代码都希望对类名&#34; has-error&#34;进行操作,因为它想要添加它(当验证失败时)或删除它(当验证成功时)。

也就是说,代码有一个严重的缺陷:如果对于给定的字段,实际上有一个验证函数列表,代码将运行所有这些(这很好)。但是,对于每个验证功能,它设置或清除&#34; has-error&#34; class ,不考虑先前的验证结果。如果您对验证功能的排序非常小心,可能可以工作,但这是一种非常脆弱的做事方式。我认为如果它进行每次测试并跟踪任何测试是否失败,然后在该过程完成后对于给定的字段它只会设置或清除它会更强大&#34;有错误&#34;类。

修复代码并不难。目前,它在迭代之外迭代所选字段的验证函数,我认为这是向后的。但是,只要它检查错误指示符元素的状态,就应该没问题。

首先,在顶部,代码删除&#34; has-error&#34;来自.form-group元素但不来自.input-group元素。这显然不正确,所以:

$('.form-control').closest('.form-group, .input-group').removeClass('has-error');

然后,在循环中:

        for( z = 0; z < item.selector.length; z++){
            selector = $(item.selector[z]); //setting the selector
            //attempting to set info to the closest form or input group found by the selector
            info = selector.closest('.form-group, .input-group');
            if (info.length && !fn(selector.val())) // if info contains data and field is invalid
               info.addClass('has-error');
        }

因为所有&#34;有错误&#34;标志在开始时被清除,我们需要做的就是类添加到无效的类中。如果你想要积极的&#34; is-ok&#34;然后,您可以将其添加到顶部的所有内容中,并在发现错误时将其删除。

答案 1 :(得分:2)

正如您应该知道的那样,foo.bar foo["bar"]在JavaScript中是相同的(如果您不知道,现在就学习它)。

这一行

info[fn(selector.val()) ? 'removeClass' : 'addClass']('has-error');

装置

var methodName;
if (fn(selector.val())) { methodName = 'removeClass'; } else { methodName = 'addClass'; }
info[methodName]('has-error')

所以,换句话说,

if (fn(selector.val())) {
   info.removeClass('has-error');
} else {
   info.addClass('has-error');
}

因此它实际上是打开/关闭班级has-error。只是它写得非常密集。