zoukankan      html  css  js  c++  java
  • Javascript的作用域

    一、作用域

      几乎所有的语言都有作用域的概念,简单的说,作用域就是变量和函数的可访问范围,即作用域控制在变量和函数的可见性和生命周期。

      在Javascript中,引擎、编译器和作用域共同协调完成Javascript的执行过程。

      引擎: 从头到尾负责Javascript代码的编译和执行

           编译器:负责词法的分析和代码的生成

           作用域:负责收集和维护由声明的变量组成的一系列查询,并执行一套非常严格的规则,确定当前执行的代码对这些变量的访问权限

    二、事例

      2.1 以代码块为范围的作用域  

    public void Func(){
        if(1==1){
            string name = 'java';
        }
        console.writeline(name);        
    }    
    
    Func()
    

      这段代码是会报错的,在以代码块为作用域范围的语言中,{}中的范围就是一个变量的作用域范围。作用name变量的作用域范围在if条件语句中,console.writeline是获取不到name这个变量的,可以改成:  

    public void Func(){
        if(1==1){
            string name = 'java';
            console.writeline(name);
        }
        //console.writeline(name);
    }    
    
    Func()
    

      2.2 以函数为范围的作用域  

    #python
    
    def func():
        if 1==1:
            name =  'python'
        print(name)
    
    func()
    

      这段代码是可以正常运行的,虽然name变量的声明在if的缩进内,但是python语言是以函数为作用域范围的。也就是说在函数内部,一个变量已经声明了,那么就能被接下来的代码调用。

    三、Javascript的作用域

      3.1 Javascript的作用域也是以整个函数为范围的  

    # 以整个函数为作用域范围
    
    function func(){
        
        if(1==1){
            var name = 'Javascript';
        }  
    
        console.log(name);
    }
    
    func()
    

      控制台运行:

      

       3.2 作用域在未被调用之前已经创建

      在上述代码中,编译器(浏览器)自上而下解释执行的过程中,作用域就已经明确了,不是等到调用func()函数的时候才创建完成。

      3.3 作用域嵌套

      引擎从当前的执行作用域开始查找变量,如果找不到,就向上一级继续查找,直至到最外层的全局作用域链,不管最终是否找到了变量,查找过程到到此结束。  

    name = 'bigberg';
    
    function func(){
        
        var name = 'eric';
        
        function inner(){
            var name = 'Sam';
            console.log(name);      
        }  
        
        return inner;
    }
    
    res = func();
    res();
    

      就近原则,输出的是Sam。如果把Sam这行注释掉,那结果又是什么呢?

    name = 'bigberg';
    
    function func(){
        
        var name = 'eric';
        
        function inner(){
            //var name = 'Sam';
            console.log(name);      
        }  
        
        return inner;
    }
    
    res = func();
    res();
    

      res()函数看上去是在函数范围之外执行的,输出的应该是bigberg。但是根据3.2所说,函数的作用域范围是在函数被调用之前就确定的了,那么还是就近原则,输出的应该是eric。

       那么如果做如下变动:  

    name = 'bigberg';
    
    function func(){
        
        var name = 'eric';
        
        function inner(){
            //var name = 'Sam';
            console.log(name);      
        }  
        
        var name = 'Tom';
        return inner;
    }
    
    res = func();
    res();
    

      这种情况输出的是什么呢?根据就近原则来找,inner函数中没有name这个变量,那么就往上一层找。在func函数中,编译器在解释执行时,第一次将eric赋值给了name这个变量,接下来又将Tom这个值赋值给了name变量,所以eric被Tom给覆盖了,所以res()的输出结果就应该是:Tom

      3.4 Javascript内部局部变量会声明提前  

    function func(){
        
        console.log(name);
        var name = 'bigberg';          
    }
    

      在Javascript中局部变量会被提前找到做这样一个操作,如:  

    var name = 'bigberg';
    
    var name;
    
    name = 'bigberg';
    

      如果变量没有被赋值,那么其就会被默认赋值为undefined。

      所以在上面的代码中,func()函数输出的值应该是undefined。虽然name = 'bigberg',但是在console.log(name)执行时,变量name只执行了var name这个操作,其被默认赋值为undefined。

  • 相关阅读:
    四、MYSQL的数据类型
    一、InnoDB引擎
    Spring源码分析(一)
    ActiveMQ 的安装与使用(springboot版本)
    12、JAVA内存模型与线程
    9、虚拟机字节码执行引擎
    8、类加载机制
    7、Class文件的格式
    6、使用jconsole+VisualVM分析JVM
    5、JVM的监控与分析工具
  • 原文地址:https://www.cnblogs.com/bigberg/p/9420293.html
Copyright © 2011-2022 走看看