zoukankan      html  css  js  c++  java
  • JavaScript变量存储浅析(一)

    Hello!

      上一篇关于JS中函数传参(http://www.cnblogs.com/souvenir/p/4969092.html)的介绍中提到了JS的另外一个基本概念:JS变量存储,

      今天我们就用一个简单的JS DEMO来开始介绍这个概念。

    1 var a = 100;
    2  
    3 function func(){
    4     console.log(a);
    5     var a=200;
    6     console.log(a);
    7 }
    8  
    9 func();

      相信大家心里面已经有了各自的答案。

      ....

      来看下实际的运行结果:

      

      纳尼!怎么会酱紫?我们明明定义了一个全局变量a,按照JS作用域链的理论,func应该可以访问到全部变量a的啊?

      是的,按照作用域链的思想,func函数在运行时,在其局部变量内找不到a变量的话,理应向上在全部作用局中继续查找。

      问题就出在函数内部的 var a =200; 这句局部变量定义。

      我们都知道JS变量类型是松散型,松散型的意思并不是说JS变量就没有变量类型,而是其变量类型是在运行时才进行确定。

      来看一个DEMO:

    1 var str;
    2 
    3 str=2015;

      第一行我们定义了一个变量str,但是并未赋值,这时候JS并不知道str变量的类型,等到脚本运行到第3行,我们给str变量赋了一个值:2015.

      这时候JS才知道,哦,原来str的值是2015,这不就是Number类型吗,这才确定了str的类型。

      

      这让我想起了JS的另一个概念,叫作函数声明提升!

      把最开始的DEMO改造下:

     1 var a = 100;
     2 
     3 func();
     4  
     5 function func(){
     6     console.log(a);
     7     var a=200;
     8     console.log(a);
     9 }
    10  

      将函数的声明放在了最后,但是代码仍然可以正常运行,并不会出现func未定义的错误。

      函数声明提升就说明JS在运行之前还会经历另外一个过程:预加载。(有些地方也叫作预编译)

      在预加载阶段,JS主要对全局作用域、函数的运行环境以及作用域链等进行准备,

      这里的函数运行环境就是指:读取变量定义并确定其属于哪个作用域,但不会为其赋值!

      

      到这里我们终于要开始解释文章一开始提出的问题了(可憋死宝宝了(づ。◕‿‿◕。)づ):

      我们就来分解一下预加载阶段,JS都做了什么事情:

    1 var a = 100;    //定义一个全部变量
    2   
    3 func();
    4 
    5 function func(){
    6     console.log(a);
    7     var a=200;        //定义一个func局部变量
    8     console.log(a);
    9 }

      在预加载阶段,第一行的时候定义了一个全部变量a,然后到了第7行,又给func定义了一个局部变量a,

      注意这个时候变量并未赋值,值均为undefined

      到了运行阶段:

      第一行给全部变量a赋了值:100,等到执行func函数的时候,

      在第6行,需要使用a变量,JS当然是先查找func的局部变量了,没错,预加载阶段已经为func定义了一个局部变量a,

      所以JS当然不会继续往全局进行查找了,但是使用的时候才发现居然没有值,也就是undefined!

      等到第7行JS才给局部变量a赋值。

      小结:

        JS分为预加载和执行期两个阶段,前者只会确定变量的作用域,在执行期才会对齐进行赋值,同时也就确定了变量的具体类型。

      

      

      

       下一篇(http://www.cnblogs.com/souvenir/p/4969565.html)我们将继续介绍JS中变量的存储原理,只不过这次我们重点要看的是对象!

      

      

      

      

  • 相关阅读:
    pycharm如何快速替换代码中的字符
    tcp三次握手四次挥手那些事
    Python之异常处理
    Python之单例模式
    ApplicationContext
    ContextLoaderListener作用详解
    DispatcherServlet--Spring的前置控制器作用简介
    web.xml中servlet的配置
    Hibernate各种主键生成策略与配置详解【附1--<generator class="foreign">】
    java.util.ConcurrentModificationException 解决办法(转)
  • 原文地址:https://www.cnblogs.com/souvenir/p/4969399.html
Copyright © 2011-2022 走看看