zoukankan      html  css  js  c++  java
  • JS 变量作用域

    变量作用域
    有作用范围和生命周期。

    静态作用域:
    词法作用呀,由程序的定义位置决定,在编译的时候就决定了生存周期和作用范围。
    跟代码执行顺序无关,通过代码嵌套来解析。

    例子:

        var x = 10;
        function fun () {    //编译的时候,X已经初始化了。
            alert(x);
        }
        function foo () {
            var x = 20;
            fun();            //运行fun的时候,x已经编译过了,就是10
        }
    
        foo();        //10

     


    动态作用:
    程序运行时决定的。类似于C++的动态绑定。
    跟代码的执行顺序有关。
    通过栈来解决,从上到下找最近的一个。


    JS的变量作用域
    JS使用静态作用域
    JS没有块级作用域的概念,但是ES6的出现,导致了又了,let。其实ES6,没什么高深,只是加了一些语法规则,
    抄抄这个语言,那个语言而已。

    ES5中有个词法环境的概念。用来管理静态作用域

    词法环境。描述环境的对象。

    环境记录:记录环境里面的
    -形参
    -函数声明
    -变量

    对外部环境的引用(outer)

    环境记录的初始化:也就是声明提前。类似于C语言的函数声明。
    执行前,先扫描函数内容,先定义到环境记录里面。

     

        var x = 10;
        function foo (y) {
            var z = 30;
            function fun (x) {    
                alert(x + y + z);
            }
            return fun;
        }
    
        //执行之前,要进行环境初始化。foo函数里面有个outer变量指向外层环境。
        var bar = foo(20);        
        bar(x);        //60
    
            环境记录初始化:
                y = 20 
           fun-->> <function> funcion内的 scope -->> 指向 foo Environment z = undefined outer -->> 指向Golbal Enverioment


    变量都是通过作用链寻找到最近的变量值。进行解析。
    通过outer指向来解决。

     

    特殊情况-with
    会创建一个临时的词法环境。
    with的outer指向global全局。 var a = 'aaa';

    <script type="text/javascript">	
    	var a = 'aaa';
    	with ({ a:'bbb'}) {
    
    		function f() {
    			alert(" f " + a);
    		};
    		(function () {
    			alert(" () " + a);	
    		})();  //这里改变了函数作用呀
    		f();
    	}
    
    
    	//先打印 ()bbb
    	//然后是  f aaa
    </script>
    	//先打印 ()bbb  匿名函数的outer指向了with作用域
    	//然后是  f aaa    f函数的outer指向了全局环境。
    因为,f函数的scope是定义在全局的。
    这里要注意的是:函数表达式和函数声明的作用域是不同的。
    函数表达式是创建的时候,被with改变了作用域。outer指向了with
    函数定义:只跟在哪里定义有关。在哪里就在哪里。而不会被with所影响。

    try ... catch

    var e = 100;
    try {
        e = 20;  //try 作用域是全局
        throw new Error();
    }
    catch (e) {
        function f() {
            alert(" f " + e);
        };
        (function () {
            alert(" () " + e);    
        })();    //这里改变了函数作用域
        f();  
    }

    // () Error 自执行的函数,作用域就是catch中的作用域

    // f 20    全局作用域。

     JS带名称的函数表达式

    (function A() {

      A = 111;
      A = function() {
        alert('B');
      };
      alert(A);
    })();

     这里的A=111;没有任何作用,函数不能被改写

    alert(A)会打印出函数A的toString的数据。

     

     

  • 相关阅读:
    泛型
    HTTP和HTTPS
    计算机网络(三)应用层
    练习38-操作列表
    第27讲:集合—在我的世界里,你就是唯一
    第25~26讲:字典:当索引不好用时
    第1~2讲:数据结构和算法绪论
    第23~24讲:这帮小兔崽子(斐波那契数列)和汉诺塔游戏
    练习36--设计和调试
    001-定义电子日历类
  • 原文地址:https://www.cnblogs.com/hgonlywj/p/4857498.html
Copyright © 2011-2022 走看看