zoukankan      html  css  js  c++  java
  • 全局预处理与执行,作用域与作用域链

    一.全局预处理

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>全局预处理:首先会创建一个词法环境(Lexical Environment),然后扫面全局里用var声明的变量和
            用声明的方式创建的函数即function xxx(){代码段}</p>
        <p>扫描后把用var声明的变量存入写成【 a:undefined  】;把声明的方式创建的函数存入写成 【xxx:指向函数或对函数的一个引用】</p>
        <script>
            alert(a); 弹出undefined,因为被存入为【a:undefined】
            alert(b); 弹出undefined,因为被存入为【b:undefined】
            alert(c); 弹出undefined,因为c是使用函数表达式创建的函数,可以当作var声明的变量,存入【c:undefined】
            alert(f); 弹出function f() { console.log('ff')},指向f的函数
            //alert(d);//此处执行到d报错【Uncaught ReferenceError: d is not defined at】
            var a=1;
            var b;
            d=5;
            alert(d); 弹出5
            function f(){
                console.log('ff');
            }
            var c=function (){//此时由于使用函数表达式创建的函数,所以可以当作用var声明的变量
                console.log('ccc');
            }
        </script>
    </body>
    </html>

    二.全局预处理与执行

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>js会从上往下扫描解读js代码</p>
        <p>预处理扫描阶段:先扫描var=a变量并js解析器储存为a:undefined,和声明的函数存为d:指向函数的引用。此时扫描完后即几个alert都
            弹出过后,遇到var a=1;则此时将先前存的【a:undefined]改为值【a:1】等等</p>
        <p>执行阶段:与预处理不同,直接扫描到c=2就直接存入显示c:2</p>
        <script>
            alert(a); undefined
            alert(b); undefined
            //alert(c);此处会报错,因为c不是用var声明的变量
            alert(d); 指向函数d
            alert(e); undefined
            var a=1;
            var b;
            c=2;
            alert(c);
            function d(){
                console.log('ddd');
            }
            var e=function(){
                consolu.log('eee');
            }
        </script>
    </body>
    </html>

    三.函数预处理与执行

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>对于函数的预处理与执行:首先会扫描函数的参数,再扫描 函数内部声明式函数,再内部var变量</p>
        <p>所以下面的首先词法环境会存入参数a:1,b:2(因为参数已经传入所以先扫描存入参数,若形参两个为ab,而实参传入一个
            则第二个参数值为undefined) </p>
        <p>之后预处理,则函数内部声明的函数命名与之前的参数冲突,函数覆盖,故此时a由【a:1】变为【a:指向函数或者对函数的引用】指向函数的引用,  同时内
            部var声明的变量也有冲突为忽略,则b值依旧为2</p>
        <p>预处理结束后执行阶段:此时弹出的a为函数的引用,b为2</p>
        <script>
            function f(a,b){
                alert(a);
                alert(b);
                var b=100;
                function a(){
                    console.log('gggg');
                }
            }
            f(1,2);  先弹出,function a(){ console.log('gggg')} ,再弹出2
         f(1);   先弹出,function a(){ console.log('gggg')} ,再弹出undefined
    </script> </body> </html>

    四.变量与函数命名冲突

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>函数为第一优先级,碰到函数命名与其他有冲突会覆盖,碰到变量与其他有冲突会忽略</p>
        <script>
            alert(a); 弹出function a() { console.log('ggg')}
            var a=1;//此处处理变量和函数冲突与前后顺序无关,均为函数优先
            function a(){
                console.log('fff');
            }
            function a(){//处理两函数冲突则后者函数会覆盖函数
                console.log('ggg');
            }
        </script>
    </body>
    </html>

    五.作用域

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>js不是块作用域,也无动态作用域,js是词法作用域也可称为静态作用域或者闭包</p>
        <p>创建函数时给函数添加一个成员scope</p>
        <script>
            var x=10;
            function ff(){//(js解析器从上到下解析时)给函数添加一个scope==创建函数时的词法环境==window
                alert(x);//此处解析出要弹出一个变量x,而ff函数未定义x,所以去其scope找也未找到再去window找,
            }
            function ff1(){
                var x=9;
                ff();//在此处调用函数执行时创建一个自己的词法环境  与  scope关联起来(而scope==window)
            }
            function ff2(){
                var x=8;
            function g(){ alert(x)} g(); } ff1();
    //弹出10 因为先解析ff函数,这是他的scope与window已绑定,在ff1调用是就只能弹出10
         ff2(); // 弹出8
    </script> </body> </html>

    六.作用域链

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <script>
            function f(){//f在js解析器从上到下解析时创建的scope(作用域) == window
                //f被调用时创建自己的词法环境(Lexical Environment)  与  f的scope(作用域)关联起来
                var x=10;//把x=10加入f的Lx中
                function g(){//创建函数g时的scope(作用域) == f的词法环境(Lx),即创建时预处理会把变量和函数都加入f的此法环境中
               //g运行时g会创建自己的词法环境(Lx)== g的scope(作用域)
                }
                g();//调用g函数
            }
            //作用域链为 :g(Lx)-->g[scope]-->f(Lx)-->f[scope]-->window
        </script>
    </body>
    </html>

    七.有关new Function

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>创建函数的方式</p>
        <p>第一:function f(){代码段}。常用</p>
        <p>第二:var g = function (){代码段}。常用</p>
        <p>另第二:var g = function f(argument){代码段}。此处f访问不到不常用</p>
        <p>第三:var g = new Function ("参数","函数体")</p>
        <p>像之前所说的作用域链,用new Function创建的函数作用域永远指向全局,而不是父函数</p>
        <script>
            //第一种情况
         var x = 100; function f(){ var x=10; var g=function (){ alert(x); } g(); } f();//由于作用域链原因最终结果弹出10,而不是100

    //第二种情况 var x=100; function f (){ var x=10; var g = new Function ("","alert(x)"); g(); } f();//由于用new Function创建的函数作用域永远指向全局,而不是父函数,故只有在全局声明x才能弹出值,且弹出为100 </script> </body> </html>

     八.作用域用途

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>作用域用途:信息隐藏,减少全局变量及其命名冲突的发生</p>
        <p>为了减少全局变量,将全局变量放入一个匿名立即调用函数</p>
        <script>
            (function(){   //(function(){})()为自调用函数
                var a=10;
                var b=20;//将ab设为局部变量
                function f(){
                    alert(a);
                }
                window.f=f;
            })();
            f();//弹出10,可以在外部调用f函数,但是不能在外部访问ab变量,而且局部变量ab不会被垃圾回收机制回收
         console.log(a) // 弹出Uncaught ReferenceError: a is not defined at
    </script>
    </body>
    </html>
  • 相关阅读:
    网页、JavaScript 数据类型
    网页javascript
    网页CSS
    使用ButterKnife无法inject view的解决办法
    项目管理实践 -- 健身小管家(Fitness housekeeper)的管理
    XML的序列化与反序列化
    JAVA虚拟机JVM-7.多线程常见问题刨析
    JAVA虚拟机JVM-6.锁优化
    JAVA虚拟机JVM-5.多线程以及锁
    JAVA虚拟机JVM-4.线程模型
  • 原文地址:https://www.cnblogs.com/forever-xuehf/p/8982582.html
Copyright © 2011-2022 走看看