开发者问题收集

Javascript:未捕获的类型错误:无法读取未定义的属性“长度”

2017-07-16
4293

我编写了一个脚本来验证通过表单提交的用户名。如果用户名超过 5 个字符,它应该向用户显示一些消息。 我收到的错误是

:Uncaught TypeError: Cannot read property 'length' of undefined at checkusername (eventobject.html:24) at HTMLInputElement. (eventobject.html:18)

我使用了“blur”事件。

代码是:

 <html>

<head>
</head>

<body>

  <form>
    <label for="text">Username:</label>
    <input type="text" id="text" />
    <p id="para"></p>

  </form>

  <script>
    var el=document.getElementById("text");
    el.addEventListener('blur',function(){checkusername(5);},false);

    var msg=document.getElementById("para");

    function checkusername(min)
    {
     if(this.value.length<min)
     {
       msg.textContent="username less than 5 characters";
     }
     else
     {
      msg.textContent='';
     }
    }

  </script>
</body>


</html>

当我编写不带参数的相同事件处理程序时,上述代码运行良好。 不传递参数的事件处理代码如下所示:

<html>

<head>
</head>

<body>

  <form>
    <label for="text">Username:</label>
    <input type="text" id="text" />
    <p id="para"></p>

  </form>

  <script>
    var el=document.getElementById("text");

    el.addEventListener('blur',checkusername,false);

    var msg=document.getElementById("para");

    function checkusername()
    {
     if(this.value.length<5)
     {
       msg.textContent="username less than 5 characters";
     }
     else
     {
      msg.textContent='';
     }
    }

  </script>
</body>


</html>
3个回答

您可以使用 Function.prototype.bind()this 设置为第一个参数,并将在函数体中使用的参数设置为第二个到 N 个参数,并将其传递给 .bind()

el.addEventListener('blur',checkusername.bind(el, 5 /*, N */),false);
guest271314
2017-07-16

在研究了事件的调用方式后,我找到了两种解决上述问题的方法。 再看看错误信息:-

:Uncaught TypeError: Cannot read property **'length'** of undefined at **checkusername** 

从上面的消息可以清楚地看出,错误发生在 checkusername() 函数内部。实际错误发生的原因是将长度应用于 undefined 变量,在此上下文中为 this

在此事件调用中 this 未定义的原因:

1.在常规函数调用中(如下所示),关键字 this 与调用该函数的事件相关联。

el.addEventListener('blur',checkusername(),false); //call without parameters

在这里,事件直接调用函数 checkusername() 。简而言之, this 持有对 el 的引用,即 this-->el。 在这种事件调用中,在 this 上使用 length 属性是有意义的,因为它保存了一些东西。

2.在涉及传递参数的函数调用(问题中的问题)中,根据 JavaScript 标准,常规函数调用不受支持。 JavaScript 定义函数调用需要嵌入在匿名函数中(如下所示):

el.addEventListener('blur',function(){checkusername(5);},false); //call with parameters.

此处,event 调用匿名函数,而匿名函数又调用 checkusername()。 因此, this 不引用任何内容, 未定义 。因此,在 checkusername 内对 this 调用 length 将返回错误。

由于 this 无法使用,因此使用以下技术。

方法 1: :将 el 作为参数列表的一部分传递。

var el=document.getElementById("text");
el.addEventListener('blur',function(){checkusername(el,5);},false);

var msg=document.getElementById("para");

function checkusername(el,min)
{

    if(el.value.length<min)
    {
        msg.textContent="username less than 5 characters";
    }
    else
    {
        msg.textContent='';
    }
}

方法 2 :全局声明 el

var el=document.getElementById("text");
    el.addEventListener('blur',function(){checkusername(5);},false);

    var msg=document.getElementById("para");

    function checkusername(min)
    {

        if(el.value.length<min)
        {
            msg.textContent="username less than 5 characters";
        }
        else
        {
            msg.textContent='';
        }
    }

在以下位置找到了这些解决方案 Jon Duckett 撰写的 Javascript&JQuery 书籍。 有用的链接

希望这对您有所帮助。:) 我在 stackoverflow 上的第一个回答。

Imran pasha
2017-07-18

试试这个 -

  <!DOCTYPE html>
     <html> 
        <body>
        <form>
            <label for="inputText">Username:</label>
            <input type="text" id="inputText" />
            <p id="message"></p>
        </form>

        <script>
            var el=document.getElementById("inputText");
            el.addEventListener('blur',function(){checkusername(5);},false);

            var msg=document.getElementById("message");

            function checkusername (min) {
                if(this.el.value !== (undefined || null) && this.el.value.length < min) {
                    msg.textContent="username less than 5 characters";
                } else {
                    msg.textContent='';
                }
            }

        </script>    
    </body>    
</html>
rahul
2017-07-18