首先看一段代码

<!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解析器的执行原理的更多相关文章

  1. node npm --save,不同JS解析器的内置全局变量,PROMISE,CONST---ES6

    npm  --save 当你为你的模块安装一个依赖模块时,正常情况下你得先安装他们(在模块根目录下npm install module-name),然后连同版本号手动将他们添加到模块配置文件packa ...

  2. [Java多线程]-线程池的基本使用和部分源码解析(创建,执行原理)

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 多线 ...

  3. TypeScript 装饰器的执行原理

    装饰器本质上提供了对被装饰对象 Property​ Descriptor 的操作,在运行时被调用. 因为对于同一对象来说,可同时运用多个装饰器,然后装饰器中又可对被装饰对象进行任意的修改甚至是替换掉实 ...

  4. js解析器(重要!)

    JavaScript有"预解析"的特性,理解预解析是很重要的,不然在实际开发中可能会遇到很多无法解析的问题,甚至导致程序bug的存在. #js预解析执行过程: 预解析:(全局作用域 ...

  5. js解析器

    1>js的预解析 找var function 参数等 所有的变量,在正式运行代码前,都提前赋了一个值:未定义 所有的函数,在正式运行代码前,都是整个函数块. 遇到重名的:只留一个 如果变量与函数 ...

  6. JS循环嵌套的执行原理

    [逆战班] 循环嵌套是指在一个循环语句中再定义一个循环语句的语法结构,外循环执行一次,内循环全部执行完,直到外循环执行完毕,整个循环结束. while.do.. while和for循环语句都可以进行嵌 ...

  7. javascript解析器原理

    浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤 1. “找一些东西”: v ...

  8. 浏览器中“JavaScript解析器”工作原理

    浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤: 1.“找一些东西”: v ...

  9. 深入浅出 Vue.js 第九章 解析器---学习笔记

    本文结合 Vue 源码进行学习 学习时,根据 github 上 Vue 项目的 package.json 文件,可知版本为 2.6.10 解析器 一.解析器的作用 解析器的作用就是将模版解析成 AST ...

随机推荐

  1. JPA 注解的CascadeType属性

    cascade表示级联操作,在表之间的关系映射时用到 CascadeType.MERGE级联更新:若items属性修改了那么order对象保存时同时修改items里的对象.对应EntityManage ...

  2. python之time模块

    from time import * ''' class struct_time(tuple): pass ''' tuple1 = (, , , , , , , , ) s = struct_tim ...

  3. Redis常见的应用场景解析

    Redis是一个key-value存储系统,现在在各种系统中的使用越来越多,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景. Redis特性 一个产品的使用场 ...

  4. C的函数指针与指针函数

    1.函数指针 指向函数的指针.本质是一个指针. 指针变量可以指向变量的地址.数组.字符串.动态分配地址,同时也可指向一个函数,每个函数在编译的时候,系统会分配给该函数一个入口地址,函数名表示这个入口地 ...

  5. .NET第四章总结

    .NET第四章简单总结 1.简单的获取文件路径:                    2.回车跳转控件焦点    3.*************无标题窗体拖动!!************* 1): ...

  6. OpenVPN server端配置文件详细说明(转)

    本文将介绍如何配置OpenVPN服务器端的配置文件.在Windows系统中,该配置文件一般叫做server.ovpn:在Linux/BSD系统中,该配置文件一般叫做server.conf.虽然配置文件 ...

  7. Web的架构与html5基础知识

    图1:完整的Web应用构架 图2:html5的基本结构 head 可添加在头部标签元素有→→title meta style link base script noscript meta 几个重要属性 ...

  8. ajax url参数中文乱码解决方法

    较好的处理办法,对js的url中的中文参数值使用两次encodeURI(),即encodeURI(encodeURI("url的中文参数值")) JS代码: var name=&q ...

  9. java关于随机数和方法重构

    1.生成随机数 源代码 package Zuote; public class SuiJiShu { public static void main( String args[] ) { java.u ...

  10. 规划自己的生活,从使用GTD时间管理法开始

    前言 为了不再浪费时间,不在茫然度过每一天,我为自己应用了GTD时间管理法,之前并不知道这种方法,实际和我自己定制的也差不太多,下面说说这个方法.   一.GTD时间管理 时间管理法有很多,而GTD( ...