js解析器的执行原理

首先看一段代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <span>我是span</span>
        <script type="text/javascript">
           alert(cnt);
            var cnt=60;
            function huoqu(){

            }

        </script>
    </body>
</html>    

代码的执行顺序是从上往下的,当代码执行到script标签时,也就开始执行js代码了。

执行js代码一般分两步:1.预解析代码。   2.逐行执行代码。

第一步:预解析代码

预解析代码呢,主要会把var , function , 参数等一些东西 存储进仓库里面(内存)。

1.var 一般用于声明变量,预解析代码的时候,等号后面的赋值过程不会执行,所以预解析时的var 变量 都是未定义的。

2,.function 函数呢,预解析的时候,值就是函数里面的内容。

当变量和函数重名时:就只留下函数的值,不管顺序谁前谁后。所以函数的优先级比变量高。注意:这只是预解析。

当函数和函数重名时:会留下后面那个,会遵循上下文机制。

第二步:逐行执行代码

当预解析完成之后,就开始逐行执行代码了,全部代码都会完整的执行。

实例:下面的alert分别会弹出什么值

 1 <script>
 2    alert(a);
 3    var a=1;
 4    function a(){alert(2);}
 5    alert(a);
 6    var a=3;
 7    alert(a);
 8    function a(){alert(4);}
 9    alert(a);
10 </script>

第一步:预解析

上面说过,预解析时只会把var , function ,参数等存储起来,所以:

执行到第二行时,a 的值是未定义。

执行到第四行时,a 的值是函数本身,也就是function a(){alert(2);}。

执行到第六行时,a 的值还是第四行时的值,也就是function a(){alert(2);},因为函数的优先级比变量高。

执行到第八行时,a 的值就变成了function a(){alert(4);} ,因为当两个函数重名时,遵循代码从上往下执行。

第二步:代码逐行执行

预解析完成之后,就是代码逐行执行了,

第二行:会弹出function a(){alert(4);} ,因为预解析完成之后,被存进内存的a 的值就是function a(){alert(4);}

第三行:第三行里有表达式,a 被赋了一个新的值1  表达式会改变变量的值。表达式可以改变预解析的值。

第四行:只是函数的声明,并没有用到表达式,而且也没有函数的调用,所以不会改变a 的值。

第五行:因为a 的值没有变化,所以还是1

第六行:使用了表达式,a 被赋了一个新的值3

第七行:会弹出3

第八行:函数的声明,不会改变a 的值。

第九行:a的值没有改变,所以还是3

最后结果为:

<script>
 2    alert(a);//弹出function a(){alert(4)}
 3    var a=1;
 4    function a(){alert(2);}
 5    alert(a);//弹出1
 6    var a=3;
 7    alert(a);//弹出3
 8    function a(){alert(4);}
 9    alert(a);//弹出3
10 </script>
时间: 2024-08-18 11:31:24

js解析器的执行原理的相关文章

js---07 js解析器作用域

js解析器首先不会逐行读代码,这是第二部了. 首先 根据var找到变量,根据function找函数,找到变量var a = 1,js解析器只会读取等号前面的var a,并把a设置值未定义,并不会读取等号后面的a = 1,所以a的值是未定义,并加入仓库,根据function找到函数后,function a (){ alert(2); },找到函数是函数整体,这是js的预解析(预解析只找var 和函数).遇到重名的留下后面的,变量和函数重名了,函数在后面,只留下函数. 正式读取代码的时候,是从上到下

TypeScript 装饰器的执行原理

装饰器本质上提供了对被装饰对象 Property? Descriptor 的操作,在运行时被调用. 因为对于同一对象来说,可同时运用多个装饰器,然后装饰器中又可对被装饰对象进行任意的修改甚至是替换掉实现,直观感觉会有一些主观认知上的错觉,需要通过代码来验证一下. 比如,假若每个装饰器都对被装饰对象的有替换,其结果会怎样? 多个装饰器的应用 通过编译运行以下示例代码并查看其结果可以得到一些直观感受: function f() { console.log("f(): evaluated")

js解析器

1>js的预解析 找var function 参数等 所有的变量,在正式运行代码前,都提前赋了一个值:未定义 所有的函数,在正式运行代码前,都是整个函数块. 遇到重名的:只留一个 如果变量与函数重名,则留下函数,如果级别相同,则留下面的. 2>逐行解析代码 表达式:= + - * / ++ -- ! 参数.... 表达式可以修改预解析的值 例: alert(a); //function a(){alert(4);} var a=1; //1 function a(){alert(2);} al

JS循环嵌套的执行原理

[逆战班] 循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,外循环执行一次,内循环全部执行完,直到外循环执行完毕,整个循环结束. while.do.. while和for循环语句都可以进行嵌套,并且他们之间可以进行互相嵌套.最常见的是在for循环中嵌套for循环.格式如下: for (循环变量初始值; 循环条件; 步长) { 循环体 ....... for (循环变量初始值; 循环条件; 步长) { 循环体 ........ } } 例子一: 利用循环嵌套输出一个金字塔形状的三角形:

javascript解析器原理

浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的"JavaScript解析器"开始工作. JavaScript解析器工作步骤 1. "找一些东西": var. function. 参数:(也被称之为预解析) 备注:如果遇到重名分为以下两种情况: (1) 遇到变量和函数重名了,只留下函数 (2) 遇到函数重名了,根据代码的上下文顺序,留下最后一个 2. 逐行解读代码 备注:表达式可以修改预解析的值 JS解析器在执行第一步

JS解析机制

变量和函数的声明在js预编译器被处理,而变量的初始化过程和函数的执行发生在执行期,执行期JS解析器按照代码顺序进行解析执行. 在函数声明之前调用函数也是合法的. f(); //返回值1 function f() { alert(1); } 但是按照下面方式声明函数,JS解释器会报语法错误. f(); //返回语法错误 var f = function() { alert(1); } 虽然变量和函数的声明可以放在文档的任意位置,但是良好的编程习惯应该是在JS代码之前声明全局变量和函数并为全局变量初

Python 之父再发文:构建一个 PEG 解析器

花下猫语: Python 之父在 Medium 上开了博客,现在写了两篇文章,本文是第二篇的译文.前一篇的译文 在此 ,宣布了将要用 PEG 解析器来替换当前的 pgen 解析器. 本文主要介绍了构建一个 PEG 解析器的大体思路,并介绍了一些基本的语法规则.根据 Python 之父的描述,这个 PEG 解析器还是一个很笼统的实验品,而他也预告了,将会在以后的系列文章中丰富这个解析器. 阅读这篇文章就像在读一篇教程,虽然很难看懂,但是感觉很奇妙:我们竟然可以见证 Python 之父如何考虑问题.

面试题|手写JSON解析器

这周的 Cassidoo 的每周简讯有这么一个面试题:: 写一个函数,这个函数接收一个正确的 JSON 字符串并将其转化为一个对象(或字典,映射等,这取决于你选择的语言).示例输入: fakeParseJSON('{ "data": { "fish": "cake", "array": [1,2,3], "children": [ { "something": "else&qu

springMVC整理03--处理数据模型 &amp; 试图解析器 &amp; @ResponseBody &amp; HttpEntity

1.处理模型数据 SpringMVC 中的模型数据是非常重要的,因为 MVC 中的控制(C)请求处理业务逻辑来生成数据模型(M),而视图(V)就是为了渲染数据模型的数据.当有一个查询的请求,控制器(C)会把请求拦截下来,然后把根据请求的内容对它进行分配适合的处理方法,在处理方法上进行处理查询的业务逻辑,得到了数据,再把数据封装成数据模型对象,最后把数据模型(M)对象传给了视图(V),让视图去渲染数据模型.SpringMVC 提供了以下几种途径输出模型数据: ModelAndView:处理方法返回