Javascript的作用域

Posted Bigberg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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。

 

以上是关于Javascript的作用域的主要内容,如果未能解决你的问题,请参考以下文章

JS---闭包

JS 作用域及作用域链

JS 作用域及作用域链

JavaScript ES6 的let和const

Javascript代码片段在drupal中不起作用

初入AngularJS基础门