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分别会弹出什么值
<script>
alert(a);
var a=1;
function a(){alert(2);}
alert(a);
var a=3;
alert(a);
function a(){alert(4);}
alert(a);
</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>
js解析器的执行原理的更多相关文章
- node npm --save,不同JS解析器的内置全局变量,PROMISE,CONST---ES6
npm --save 当你为你的模块安装一个依赖模块时,正常情况下你得先安装他们(在模块根目录下npm install module-name),然后连同版本号手动将他们添加到模块配置文件packa ...
- [Java多线程]-线程池的基本使用和部分源码解析(创建,执行原理)
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 多线 ...
- TypeScript 装饰器的执行原理
装饰器本质上提供了对被装饰对象 Property Descriptor 的操作,在运行时被调用. 因为对于同一对象来说,可同时运用多个装饰器,然后装饰器中又可对被装饰对象进行任意的修改甚至是替换掉实 ...
- js解析器(重要!)
JavaScript有"预解析"的特性,理解预解析是很重要的,不然在实际开发中可能会遇到很多无法解析的问题,甚至导致程序bug的存在. #js预解析执行过程: 预解析:(全局作用域 ...
- js解析器
1>js的预解析 找var function 参数等 所有的变量,在正式运行代码前,都提前赋了一个值:未定义 所有的函数,在正式运行代码前,都是整个函数块. 遇到重名的:只留一个 如果变量与函数 ...
- JS循环嵌套的执行原理
[逆战班] 循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,外循环执行一次,内循环全部执行完,直到外循环执行完毕,整个循环结束. while.do.. while和for循环语句都可以进行嵌 ...
- javascript解析器原理
浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤 1. “找一些东西”: v ...
- 浏览器中“JavaScript解析器”工作原理
浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤: 1.“找一些东西”: v ...
- 深入浅出 Vue.js 第九章 解析器---学习笔记
本文结合 Vue 源码进行学习 学习时,根据 github 上 Vue 项目的 package.json 文件,可知版本为 2.6.10 解析器 一.解析器的作用 解析器的作用就是将模版解析成 AST ...
随机推荐
- oracle-获取数据库中所有表的注释 comments
公司dba提供的脚本: set serveroutput on set feedback off spool /tmp/getcomments.out select 'comment on table ...
- linux下Nginx配置文件(nginx.conf)配置设置详解(windows用phpstudy集成)
linux备份nginx.conf文件举例: cp /usr/local/nginx/nginx.conf /usr/local/nginx/nginx.conf-20171111(日期) 在进程列表 ...
- JS之脚本延迟
自从开了博客,我就一下班回来匆匆吃完饭门一关等一开电脑一打开匆匆的研究东西,以至于朋友们都怀疑我是不是都得了自闭症 其实因为我有恐惧心理怕自己的技术哪天跟不上社会了,说到技术我觉得技术不求越新越好,但 ...
- noip的一些模板(参考了神牛的博客)
一.图论 1.单源最短路 洛谷P3371 (1)spfa 已加SLF优化 419ms #include <iostream> #include <cstdio> #includ ...
- Split分割字符串
第一种方法:打开vs.net新建一个控制台项目.然后在Main()方法下输入下面的程序. string s="abcdeabcdeabcde"; string[] sArray=s ...
- bzoj4236 JOIOJI hash 模拟
JOIOJI桑是JOI君的叔叔."JOIOJI"这个名字是由"J.O.I"三个字母各两个构成的. 最近,JOIOJI桑有了一个孩子.JOIOJI桑想让自己孩子的 ...
- PHP和JS判断变量是否定义
PHP中: 通过isset(变量名)来判断,定义返回true/未定义返回false JS中: 通过typeof来判断.
- Java历程-初学篇 Day07 循环结构2 for循环
一,格式 for(赋值语句//为循环变量赋初值;条件语句//循环结构的循环条件;赋值语句//迭代,修改循环变量的值){ //循环体; } 二,简单举例 for(int i=1;i<=10;i++ ...
- PL/SQL 三个小例子
/* SQL语句 员工集合:select to_char(hiredate,'yyyy') from emp --> 光标 --> 循环--> 退出条件:notfound 变量 co ...
- SVN版本控制图标经常延时显示或未显示问题解决方法
项目中,使用svn经常遇到,文件或文件夹图标延时显示或未显示的问题,终于找到办法解决 客户端:TortoiseSVN