zoukankan      html  css  js  c++  java
  • [转载]Js解析机制

    [转载自https://www.cnblogs.com/yesw/p/3999668.html]

    Js语句是怎么解析的(同一个作用域)

    首先会全局查找(预解析)var, function提升其优先级

        

    alert(a);
    var a = 1;

        上面的两行代码是这么解析的:

    var a;
    
    alert(a);
    
    a = 1;

        所以结果是undefined

        1.所有的变量在正式代码运行之前,都是undifined

        2.所有的函数在正式运行之前, 都是函数块(域) 

    其次解读代码:

    一些表达式(+-=*%!等)

    表达式可以修改预解析的值

    函数调用

    遇到函数域或者一个新的域  又会重复做首先, 其次的动作

    作用域链查找规则:自上而下(一个或多个sript), 由里到外查找(函数中)

    一些例子

    var a = 1;
    function foo(){
      alert(a)  ;
      var a = 2;      
    }
    
    foo();
    alert(a);
    var a = 1;
    function foo(){
     alert(a);  
     a =  2;
    }
    foo();
    alert(a);
    var a = 1;
    function foo(a){
     alert(a);
     a = 2;
    }
    foo();
    alert(a);
    var a = 1;
    
    function foo(a){
      alert(a) ;
     a = 2;
    }
    
    foo(a);
    alert(a);

    四个例子对比 带有输出值

    if和for语句都不会生成新的作用域, FF下有这样一个bug-----------不可以对if语句下的函数进行预解析,所以不要在if和for语句中定义变量或者函数

    alert(a);//undefined
    alert(fun);//FF下报错,其他浏览器会弹出fun整个函数
    if(true){
     var a = 1;
     function fun(){
      alert(2);
     }
    }

    经典问题再现:

    //三个input
    var
    obj = document.getElementsBytagName("input"); for(var i = 0; i < obj.length; i++){ alert(i);; obj[i].onclick = function(){ obj[i] .style.background = "red"; } }

    为什么 i 的值是3 而不是0,1,2?

    for语句是不存在块级作用域, 按照JS的与解析机制, 当for语句执行完毕之后, 再解析onclick函数的块级作用域,  此时for循环完毕,  所以onclick函数内的obj[3]是undfined.

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    闭包相关问题

    了解JS垃圾回收机制: 函数内部定义的变量在函数调用后, 被释放回收;   假如函数内部还定义了函数, 并且引用了变量,  此时这些变量不会被回收;

    闭包定义: 函数嵌套函数, 内部函数引用外部函数的变量或者参数, 这些变量或者参数不会被收回

    作用: 

        1.希望变量长期驻扎在内存中

        2.避免全局变量污染

        3.私有成员存在

    用法:

      1.模块化代码

    var foo = (function(){
        var a = 1;
        function f1(){
            a++;
            alert(a);
        }
    
        function f2(){
            a++;
            alert(a);
        }
    
        return {
            a:f1;
            b:f2
        }
    })();
    
    foo.a();//1
    foo.a();//2

        2.在循环中找到对应元素的索引(解决上面的经典问题)

        

    //方法一
    var obj= document.getElementsByTagName('input');
    for(var i = 0; i< obj.length; i++>){
        ( function(i){
            obj[i].onclick = function(){
                obj[i].style.background = "red";
             }         
        })(i);
    }    
    
    //方法二
    var obj = document.getElementsByTagName('input');
    for(var i = 0; i < obj.length; i++){
      obj[i].onclick = (function(i){
           return function(){
               obj[i].style.background = "red";
            }      
        })(i);
    }
  • 相关阅读:
    如何在linux系统中设置静态ip地址
    spring 学习
    java 反射机制和invoke方法
    CentoS7装机
    eclipse 添加jar包的方式
    No-args constructor for class does not exist. Register an InstanceCreator with G
    freemarker页面如何获取绝对路径basePath
    MySQL备份还原
    MySQL用户授权与权限
    CentOS7修改SSH远程连接端口
  • 原文地址:https://www.cnblogs.com/buerjiongjiong/p/10877951.html
Copyright © 2011-2022 走看看