js:作用域(局部变量和全局变量、预解析、作用域链)

1、js的作用域

(1)概念

js的作用域就是变量在某一个范围内起作用和效果,目的是为了提高程序的可靠性更重要的是减少命名冲突(在全局和局部即使变量名相同也不会出错),作用域分为全局作用域与局部作用域,根据作用域的不同,变量又分为局部变量和全局变量。

2、局部变量和全局变量

(1)全局变量:在全局作用域下的变量

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>Java Script</title>
        <script type="text/javascript">
            var welcome = function() {
                var String1="我是局部变量";
                console.log(String2);
            }
        </script>
    </head>

    <body bgcolor="aquamarine">
        <script>
        var String2="我是全局变量";
        welcome();
        </script>

    </body>

</html>

可以通过局部访问全局变量,但是不能在函数的外面访问局部变量。是局部变量还是全局变量关键是看var的位置。全局作用域在js标签内函数外。

(2)局部变量

<!DOCTYPE html>
<html>
     <head>
        <meta charset="UTF-8">
        <title>Java Script</title>
        <script type="text/javascript">
            var welcome=function() {
            var num=10;
            console.log(num);
            }
            welcome();
            console.log(num);
        </script>
    </head>
    <body  bgcolor="aquamarine">
</html>

函数外访问局部出错,局部变量只能在函数内使用

 (3)一种特殊情况:在函数内部没有声明直接赋值的变量是局部变量

<!DOCTYPE html>
<html>
     <head>
        <meta charset="UTF-8">
        <title>Java Script</title>
        <script type="text/javascript">
            var welcome=function() {
            num=10;
            console.log(num);
            }
            welcome();
            console.log(num);
        </script>
    </head>
    <body  bgcolor="aquamarine">
</html>

3、js的预解析

  • js的解析器在运行js代码的时候分为两步:预解析和代码执行
  • 预解析的时候,js引擎会把所有的var还有function提升到作用域的最前面
  • 代码执行的时候是按照代码的顺序执行的

(1)变量预解析:声明提前

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>Java Script</title>
        <script type="text/javascript">
        
        </script>
    </head>

    <body bgcolor="aquamarine">
        <script>
            console.log(num1);
            var num1 = 1;
            console.log(num1);
        </script>

    </body>

</html>

在程序中第一次输出num1之前,num1还未被声明过,如果按java和c的语法,这样是会报错的,但是javascript在执行时遵循声明提前方式,实际上是这样执行的:

var num1;     
console.log(num1);
num1 = 1; console.log(num1);

即:把声明放在当前作用域的最前面,赋值操作不进行提升

(2)变量提升:var fun =function()方式声明的函数

        <script type="text/javascript">
            fun();
             var fun =function(){
                 console.log("nihao");
             }
        </script>

 实际上执行的步骤是:

            <script type="text/javascript">
            var fun;
            fun();
             var fun =function(){
                 console.log("nihao");
             }
        </script>

(3)函数提升:把所有的函数声明提升到作用域的最前面

    <script type="text/javascript">    
            fun();
             function fun(){
                 console.log("nihao");
             }
             
        </script>

可以正常执行:

 这是因为函数的提升是把所有的函数的声明部分提升到作用域的最前面,不会调用函数

4、作用域链

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title>Java Script</title>
        <script type="text/javascript">
            var num = 90;
            function f1() {
                var num = 20;

                function f2() {
                    console.log(num);
                }
                f2();
            }
            f1();
        </script>
    </head>

    <body bgcolor="aquamarine">

</html>

内部函数可以访问外部函数的变量,是一级一级地向外层查找,这种结构称为作用域链

原文地址:https://www.cnblogs.com/zhai1997/p/11428263.html