首页 > js匿名函数作用域问题

js匿名函数作用域问题

问题已经解决,属于个例问题;不具有普遍参考性
代码如下:

(function(){
    var loginForm = document.forms.loginForm;
    var login_inputs = loginForm.getElementsByTagName('input');
    ...
    login_inputs .forEach(function(item,index,array){});
})()

代码中报错:
login_inputs is not defined
login_inputs .forEach is not a function

loginForm测试正常
开发工具sublime

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        body,legend,input,button{
            margin: 0;
            padding: 0;
            font: 21px "微软雅黑";
        }
        #loginForm{
            width: 515px;
            margin: 150px auto;
            border: 1px solid #ddd;
        }
        #loginForm legend{
            padding-left:24px;
            box-sizing: border-box;
            width: 100%;
            height: 45px;
            line-height: 45px;
            background-color: #2D2D2D;
            color: #fff;
        }
        #loginForm fieldset{
            border: none;
        }
        #loginForm div{
            margin: 30px 65px;
        }
        #login{
            width: 100%;
            height: 43px;
            line-height: 43px;
            border: none;
            text-align: center;
            color: #fff;
            background-color: #347BD0;
            cursor: pointer;
        }
        .invalid{
            border-color: red;
            color: red;    
        }
        .disabled{
            background-color: #ddd;
            cursor: default;
        }
    </style>
</head>
<body>
    <form id="loginForm" action="/login">
        <legend>手机号码登录</legend>
        <fieldset>
            <div>
                <label for="mobile">手机号:</label>
                <input id="mobile" name="mobile" type="text">
            </div>
            <div>
                <label for="password">密 码:</label>
                <input id="password" type="password" name="password">
            </div>
            <div><button id="login">登 录</button></div>
        </fieldset>
    </form>

    <script type="text/javascript">
        (function(){
            var input_modile = document.getElementById('mobile'),
                input_password = document.getElementById('password'),
                loginBtn = document.getElementById('login'),
                loginForm = document.forms.loginForm,
                login_inputs = loginForm.getElementsByTagName('input');

            login_inputs = Array.prototype.slice.call(login_inputs);
                   
            
            function addCss(elm,clazz){
                elm.classList.add(clazz);
            }
            input_modile.addEventListener('blur', function(){
                var value = input_modile.value;
                var isNext = (/1\d{10}/).test(value);
                if(isNext == false){
                    addCss(input_modile,'invalid');
                }
            });
            
            login_inputs.forEach(function(item,index,array){
                item.addEventListener('focus', function(){
                    item.className = " ";
                })
            })

            input_password.addEventListener('submit', function(){
                var value = input_password.value;
                var isNext = (/.{6,16}/).test(value);
                if(!isNext){
                    addCss(input_password,'invalid');
                } else {
                    addCss(loginBtn,'disabled');
                }
            })
        })();
    </script>
</body>
</html>

你在chrome按F12调试一下看看,在声明login_inputs这后面先console一下看看这个得到的是什么东西,然后console.log(typeof X)看看它的类型是不是数组,你下面用到了遍历数组,然后你在你js中打断点调试下看看,你发了两句代码,具体哪里问题,我也说不准,不过首先,我一般声明数组的话,会var a = new array(); 这样写,看看是不是这个的问题


你这里要用闭包,就访问不到loginForm了。

应该这样写:

(function(loginForm){
    var login_inputs = loginForm.getElementsByTagName('input');
    ...
    login_inputs .forEach(function(item,index,array){});
})(loginForm)

(function(){
    var login_inputs = loginForm.getElementsByTagName('input');
    ...
    login_inputs.forEach(function(item,index,array){});
})()

以上代码再执行前
如果loginForm未定义过,报 ReferenceError: Can't find variable: loginForm
如果loginForm定义过并且是一个DOM元素,那么login_inputs为一个NodeList对象,这个对象没有forEach方法的,所以会报forEach is not a function
想要使用Array的forEach方法,使用函数的call/apply方法

Array.prototype.forEach.call(login_inputs, function( item,index,array ){
  console.log(item);
});

已经解决问题,当匿名函数执行完;变量应该就被销毁了。
谢谢大家帮我解决问题。


输出一下loginForm?


一般来说,xxx is not defined会出现在变量未声明之前就使用的场景。

但是,重点来了,单看题主的这段代码却永远不可能出现login_inputs is not defined,因为最开始的地方已经用了var进行声明……

var login_inputs = loginForm.getElementsByTagName('input');

所以,应该是其他地方错了吧

【热门文章】
【热门文章】