在循环上使用逻辑运算符会导致矛盾

时间:2012-11-16 18:25:45

标签: javascript jquery regex for-loop logical-operators

我正在处理JavaScript中一个非常非常奇怪的问题。我正在研究一个使用jQuery循环遍历字段列表的验证器脚本。每个验证都绑定到对象上的正则表达式,如下所示:

var formats = {

      email: /[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/g,

      phone: /(?!:\A|\s)(?!(\d{1,6}\s+\D)|((\d{1,2}\s+){2,2}))(((\+\d{1,3})|(\(\+\d{1,3}\)))\s*)?((\d{1,6})|(\(\d{1,6}\)))\/?(([ -.]?)\d{1,5}){1,5}((\s*(#|x|(ext))\.?\s*)\d{1,5})?(?!:(\Z|\w|\b\s))/gm,

      numeric: /(\d+)(((.|,)\d+)+)?/g,

      url: /^((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www.))+(([a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(\/[a-zA-Z0-9%:\/-_\\?\.'~]*)?$/gi

    };

然后我创建了一个函数,它给出了两个参数,格式和测试主题,返回truefalse(只是RegExp对象的test方法的包装器):

validy.is = function(what, str) {
    return formats[what].test(str);
};

在jQuery集合中,我有INPUT个元素,其中的类根据每种格式命名:

<input type="text" class="field email" id="field-1-1" />
<input type="text" class="field phone" id="field-1-2" />
...

然后,我的验证功能如下:

    formBuilder.validate = function() {
      console.info("=== STARTING VALIDATE ===");

      var isValid = true;
      var allFields = $(".field", formBuilder.form).toArray();
      var validable = ["email","phone","numeric","url"];

      var errors = {
        "email": "Debés ingresar una dirección de e-mail válida (por ejemplo: juanperez@gmail.com).",
        "phone": "Debés ingresar un número de teléfono válido.",
        "numeric": "Debés ingresar un número.",
        "url": "Debés ingresar una dirección Web válida (por ejemplo: www.misitio.com.ar)."
      };

      for (var f = 0; f < allFields.length; f++) {

        var $field = $(allFields[f]);

        console.info($field);
        console.info("--> Field has classes: " + $field.attr("class"));

        for (var v = 0; v < validable.length; v++) {

          var validableClass = validable[v];

          if ($field.hasClass(validableClass)) {

            console.info("--> Validating against " + validableClass + " with value <<" + $field.val() + ">>");
            console.info("--> Test result: validy.is(validableClass, $field.val()) = " + vw.validy.is(validableClass, $field.val()));
            console.info("--> Last value of isValid = " + isValid);

            isValid = isValid && (validy.is(validableClass, $field.val()) ? true : false);

            console.info("--> Value of isValid is now = " + isValid);
            break;

          };

        }

        console.info("** Status of isValid: " + isValid + " **");

        if (!isValid) {

          console.info("--> Invalid field detected");
          //vw.popoverError($field, "Error", errors[validableClass]);
          break;

        };

      };

      return isValid;

    };

问题在于即使字段值有效且isValid == true,当isValid == isValid && ...操作完成时,isValid最终为false

如何true && true表达式抛出false

我知道必须有一些我看不到的愚蠢,但我似乎无法找到它。任何人都可以帮助这个吗?

谢谢!

更新1

最初,行:

isValid = isValid && (validy.is(validableClass, $field.val()) ? true : false);

isValid &= validy.is(validableClass, $field.val();

更新2

在某些时候,显然test方法正在返回10而不是truefalse。但我无法确定它发生的确切时刻。

更新3

所以事实证明我误导了评论中提到的&=运营商。但...

isValid = isValid && validy.is(validableClass, $field.val());

...当falseisValid == true独立返回validy.is时返回true

更新4

根据CaffGeek的回答更改了validy.is定义:

    validy.is = function(what, str) {

      return !!formats[what].test(str);

    };

不幸的是,它没有任何效果。

2 个答案:

答案 0 :(得分:3)

我经常使用!!变量来确保变量存在并且它具有正值。

如果它是undefined或false,!!变量将返回false,如果它被定义为true或者具有值(不是0)它将返回true

答案 1 :(得分:1)

尝试更改

validy.is = function(what, str) {
    return formats[what].test(str);
};

以确保它是一个布尔结果。

validy.is = function(what, str) {
    return !!formats[what].test(str);
};

我没有测试过这个,但你不需要使用jQuery的所有循环。它基于设定。您可以通过这种方式简化代码。

formBuilder.validate = function() {
    console.info("=== STARTING VALIDATE ===");

    var isValid = true;
    var allFields = $(".field", formBuilder.form).toArray();
    var validable = ["email", "phone", "numeric", "url"];

    var errors = {
        "email": "Debés ingresar una dirección de e-mail válida (por ejemplo: juanperez@gmail.com).",
        "phone": "Debés ingresar un número de teléfono válido.",
        "numeric": "Debés ingresar un número.",
        "url": "Debés ingresar una dirección Web válida (por ejemplo: www.misitio.com.ar)."
    };

    var failedFields = $('EMPTYJQUERYSET');

    $.each(validable, function(index, className) {
        failedFields.add(
            allFields.filter('.' + className).filter(function(index) {
                return ! validy.is(validableClass, $(this).val());
            });
        );
    });

    isValid = !!(failedFields.length == 0);

    console.info("** Status of isValid: " + isValid + " **");

    if (!isValid) {
        console.info("--> Invalid field detected");
        //vw.popoverError($field, "Error", errors[validableClass]);
        break;
    };

    return isValid;
};